RFR: JDK-8323706 Move SimpleSelector and CompoundSelector to internal packages [v2]
John Hendrikx
jhendrikx at openjdk.org
Fri Jan 19 10:39:38 UTC 2024
On Fri, 19 Jan 2024 09:52:23 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:
>> modules/javafx.graphics/src/main/java/javafx/css/Selector.java line 179:
>>
>>> 177: * @throws IOException if reading from {@code DataInputStream} fails
>>> 178: */
>>> 179: protected static Selector readBinary(int bssVersion, DataInputStream is, String[] strings)
>>
>> This is an API addition, so will need an `@since 23`. Since you are adding new API here, should it be an instance method rather than a static method? Or is is called without having an instance of Selector in some cases?
>
> I'll add the `@since 23`, however it can't be called by anyone except FX itself.
>
> Some background: the readBinary/writeBinary methods are ultimately called via the publicly accessible methods `loadBinary` and `saveBinary` in `javafx.css.Stylesheet`.
>
> The reason it needs to be `protected` now is because `CompoundSelector` is using this (but IMHO, it shouldn't have). Why I say it shouldn't? That's because it already knows what it will be reading will all be `SimpleSelector`s, as it stores a counter (a `short`) and then loads that many `SimpleSelector`s. However, by not taking the direct route of using `SimpleSelector#readBinary` (and the corresponding `SimpleSelector#writeBinary`) there is an additional `byte` prefix indicating the type of selector -- this isn't needed and wastes some space in the binary format.
>
> Changing that now however would make the binary format incompatible with earlier versions, so I think making this `protected` is a reasonable solution. It also mirrors the `writeBinary` method then, which was already `protected`.
I missed something in my above evaluation. The counterpart method `writeBinary` is not `static`. Although that makes sense as in that case you do have an instance you wish to write, it does make the read/write API asymmetric.
It's not possible to make `readBinary` an instance method though as it is the method that is creating those instances.
The other way around is possible (make `writeBinary` static), but it would then again need a pattern match to determine the correct static `writeBinary` to call when writing an arbitrary `Selector`. However, this would have allowed `CompoundSelector` to call a static version of `SimpleSelector#writeBinary` and `readBinary`, avoiding the extra identifying byte in the binary format, and avoiding the cast when reading it back.
The read/write loops below:
+
final int nSelectors = is.readShort();
final List<SimpleSelector> selectors = new ArrayList<>();
for (int n=0; n<nSelectors; n++) {
selectors.add((SimpleSelector)Selector.readBinary(bssVersion, is,strings));
}
+
os.writeShort(selectors.size()); // writes the number of SimpleSelectors to the binary stream
for (int n=0; n< selectors.size(); n++) selectors.get(n).writeBinary(os,stringStore); // writes each individually
Would then have become:
+
final int nSelectors = is.readShort();
final List<SimpleSelector> selectors = new ArrayList<>();
for (int n=0; n<nSelectors; n++) {
selectors.add(SimpleSelector.readBinary(bssVersion, is,strings)); // cast is gone
}
+
os.writeShort(selectors.size()); // writes the number of SimpleSelectors to the binary stream
for (int n=0; n< selectors.size(); n++) SimpleSelector.writeBinaryStatic(selectors.get(n), os, stringStore); // writes each individually
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/1333#discussion_r1458762627
More information about the openjfx-dev
mailing list