On Fri, 7 Mar 2025 20:38:38 GMT, Nir Lisker <nlis...@openjdk.org> wrote:

>> 8351276: Prevent redundant computeValue calls when a chain of mappings 
>> becomes observed
>
> modules/javafx.base/src/main/java/javafx/beans/value/ObservableValue.java 
> line 378:
> 
>> 376:          * can first become observed (allowing caching) and are then 
>> queried (likely
>> 377:          * getting the value from the cache). Doing this the other way 
>> around would
>> 378:          * result in the value (or chain of values) being computed 
>> twice.
> 
> If I understand correctly, it will be computed twice because the observable 
> would not be able to cache the value yet. It will compute it once without 
> caching with `getValue()`, and then again with `addListener(...)`. If this is 
> correct, I suggest writing a short continuation: 
> "Doing this the other way around would result in the value (or chain of 
> values) being computed twice because ___."

If you add the listener first, then `ExpressionHelper` will do a `getValue` 
causing the 4 mappings to be computed but without being able to cache them as 
the bindings are not yet aware there is a listener present now (and so will 
remain "invalid").  The observable belonging to the last mapping will then have 
its `observeSources` called.  This adds another listener (on the 3rd mapping, 
via the invalidation listener endpoint, which had the same ordering issue).  
Again, `ExpressionHelper` will try get the value, and 3 mappings will be 
recomputed (the 4th mapping is not computed again as its `observeSources` was 
called already).  This continues when the listener is added on the 2nd mapping 
(and 2 mappings are recomputed), and on the first mapping (computing that one, 
one final time).

So I guess the continuation could be something like:

"... because the process of adding a listener triggers the computation of the 
observable's value which, when called before #observeSource  was called, won't 
be cached yet."

> modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueFluentBindingsTest.java
>  line 80:
> 
>> 78:             assertEquals(0, calls2.get());
>> 79:             assertEquals(0, calls3.get());
>> 80:             assertEquals(0, calls4.get());
> 
> Since these assertions are a repeating pattern, do you want to extract it to 
> a reusable method?
> 
> 
> private void assertValue(int val) {
>     assertEquals(val, calls1.get());
>     assertEquals(val, calls2.get());
>     assertEquals(val, calls3.get());
>     assertEquals(val, calls4.get());
> }

Not really, I'd prefer to be explicit in tests.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1730#discussion_r1985815678
PR Review Comment: https://git.openjdk.org/jfx/pull/1730#discussion_r1985816609

Reply via email to