Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

HV-2127 Make Path implementation not rely on Lists (or other collections) #1672

New issue

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

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

Already on GitHub? Sign in to your account

Merged

Conversation

Copy link
Member

@marko-bekhta marko-bekhta commented Aug 6, 2025

https://hibernate.atlassian.net/browse/HV-2127


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on licensing, please check here.


Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
Copy link
Member Author

@marko-bekhta marko-bekhta left a comment

Choose a reason for hiding this comment

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

Can be looked at by commit. The general idea here was to drop the use of the lists in the path implementation and just build the "chain" from the nodes.
One "downside" of this is that we do not have an easy way to iterate the path from the "root" as we only have the leaf node. If we add the root to the path, it won't help much since we
have the one-way links to the parent. I think adding the link to the leaf node won't help as we could have multiple leaves... and otherwise... reconstructing the whole path from the root to create a new leaf would probably take us back to where we were with the list ...

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

One "downside" of this is that we do not have an easy way to iterate the path from the "root" as we only have the leaf node.

But do we need to? Or does the user need to?

Copy link
Member Author

and some numbers:

main:
Benchmark Mode Cnt Score Error Units
o.h.v.p.cascaded.CascadedWithLotsOfItemsAndMoreConstraintsValidation.testCascadedValidationWithLotsOfItems thrpt 20 9210.215 ± 54.555 ops/s
o.h.v.p.simple.SimpleValidation.testSimpleBeanValidation thrpt 20 17446.229 ± 95.293 ops/ms
Benchmark Mode Cnt Score Error Units
o.h.v.p.cascaded.CascadedWithLotsOfItemsAndMoreConstraintsValidation.testCascadedValidationWithLotsOfItems thrpt 20 9447.360 ± 28.172 ops/s
o.h.v.p.simple.SimpleValidation.testSimpleBeanValidation thrpt 20 15886.786 ± 39.997 ops/ms
change:
Benchmark Mode Cnt Score Error Units
o.h.v.p.cascaded.CascadedWithLotsOfItemsAndMoreConstraintsValidation.testCascadedValidationWithLotsOfItems thrpt 20 13766.536 ± 43.834 ops/s
o.h.v.p.simple.SimpleValidation.testSimpleBeanValidation thrpt 20 26797.112 ± 80.112 ops/ms
Benchmark Mode Cnt Score Error Units
o.h.v.p.cascaded.CascadedWithLotsOfItemsAndMoreConstraintsValidation.testCascadedValidationWithLotsOfItems thrpt 20 14434.296 ± 67.744 ops/s
o.h.v.p.simple.SimpleValidation.testSimpleBeanValidation thrpt 20 23922.016 ± 89.195 ops/ms

Copy link
Member Author

One "downside" of this is that we do not have an easy way to iterate the path from the "root" as we only have the leaf node.

But do we need to? Or does the user need to?

I hope not, and I hope others would just use the string representation of the path ... but it may be that some lib goes through the path to construct the "violation" .. I'm thinking about something like org.zalando:problem (https://github.com/zalando/problem) I'll take a look at it a bit later to see what's happening there 🙈

Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
@marko-bekhta marko-bekhta force-pushed the feat/node-path-optimizations branch from 272bb90 to 25729f0 Compare August 7, 2025 13:45
Copy link
Member Author

One "downside" of this is that we do not have an easy way to iterate the path from the "root" as we only have the leaf node.

But do we need to? Or does the user need to?

I hope not, and I hope others would just use the string representation of the path ... but it may be that some lib goes through the path to construct the "violation" .. I'm thinking about something like org.zalando:problem (https://github.com/zalando/problem) I'll take a look at it a bit later to see what's happening there 🙈

ok... I had a look at Quarkus and there are a few places where the path iterator is used to construct the response... e.g.:

https://github.com/quarkusio/quarkus/blob/ebee0a4b66d1b4dba9c51165e78d22fbf3b90d3e/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/jaxrs/ResteasyReactiveViolationExceptionMapper.java#L59-L69

or here:

https://github.com/quarkusio/quarkus/blob/ebee0a4b66d1b4dba9c51165e78d22fbf3b90d3e/extensions/hibernate-validator/runtime/src/main/java/io/quarkus/hibernate/validator/runtime/interceptor/AbstractMethodValidationInterceptor.java#L155-L161

I could add some HV-specific methods to address these use cases... would Quarkus be able to leverage those?

Copy link
Member

gsmet commented Aug 7, 2025
edited
Loading

I could add some HV-specific methods to address these use cases... would Quarkus be able to leverage those?

I think I misunderstood you previously: I don't think you can break the contract of Path. It extends Iterable so iterator() should work.

Now the question is: can you somehow materialize the Path when we get a constraint violation? Because having a constraint violation is somehow a corner case. Most of the time, you shouldn't have one.

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

I added a few comments.

FWIW, we could have a specific benchmark with only things that are valid and measure the improvements there.

Then have one where we have failures to measure that things have not gone too badly for this case.

@marko-bekhta marko-bekhta force-pushed the feat/node-path-optimizations branch from 77c3615 to 73937f4 Compare August 11, 2025 12:36
@gsmet gsmet changed the title (削除) HV-2127 Make Path implementaion not rely on Lists (or other collections) (削除ここまで) (追記) HV-2127 Make Path implementation not rely on Lists (or other collections) (追記ここまで) Aug 11, 2025
Copy link
Member

gsmet commented Aug 11, 2025

@marko-bekhta were you able to re-run the benchmarks with this new code?

Copy link
Member Author

yes. it seems still better than what we currently have 🙂 here's what I saved from Friday:

main:
Benchmark Mode Cnt Score Error Units
SimpleSingleElementValidation.invalidObjectValidation thrpt 20 6474.390 ± 31.799 ops/ms
SimpleSingleElementValidation.validObjectValidation thrpt 20 17840.565 ± 51.801 ops/ms
this patch:
Benchmark Mode Cnt Score Error Units
SimpleSingleElementValidation.invalidObjectValidation thrpt 20 8527.579 ± 40.861 ops/ms
SimpleSingleElementValidation.validObjectValidation thrpt 20 33352.222 ± 402.655 ops/ms

or you mean just the few latest commits with the MaterializedPath ?

(btw ^ this is from a "new benchmark" I've added with one simple entity being either valid or invalid. I noticed that some of our other benchmarks that use random can have a quite different results from one run to the other) so I wanted to have something more "stable")

it seems still better than what we currently have

which does make sense since we do not create/copy the lists on each operation, but just create one array for the failing constraint.

Copy link
Member

gsmet commented Aug 11, 2025

(btw ^ this is from a "new benchmark" I've added with one simple entity being either valid or invalid. I noticed that some of our other benchmarks that use random can have a quite different results from one run to the other) so I wanted to have something more "stable")

Yeah, it makes perfect sense.

Looks all good to me if you want to merge it.

Copy link
Member Author

Thanks for having a look at this one, Guillaume! 🙏🏻 🙇🏻 🙂
yeah.. I should probably merge it before switching to the bean tracking PR so that there would be less problems with rebasing... I'll have a look at what Sonar suggests to fix and then merge 🙂

... node
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
...ollections.unmodifiableXxx
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
...is used
which would be the case with most constraints
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
Signed-off-by: marko-bekhta <marko.prykladna@gmail.com>
@marko-bekhta marko-bekhta force-pushed the feat/node-path-optimizations branch from 73937f4 to bb2973c Compare August 11, 2025 14:38
@marko-bekhta marko-bekhta marked this pull request as ready for review August 11, 2025 15:43
@marko-bekhta marko-bekhta merged commit 015a622 into hibernate:main Aug 11, 2025
11 checks passed
Copy link
Member

gsmet commented Aug 11, 2025

Woot! Congrats on this change, it's awesome!

marko-bekhta reacted with hooray emoji marko-bekhta reacted with heart emoji

Copy link
Member Author

thanks! Processed bean tracking is coming next 😉🤞🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@gsmet gsmet gsmet left review comments

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /