Ramin Gharib created FLINK-41110:
------------------------------------

             Summary: Find VARIANT object fields by comparing UTF-8 bytes
                 Key: FLINK-41110
                 URL: https://issues.apache.org/jira/browse/FLINK-41110
             Project: Flink
          Issue Type: Improvement
          Components: API / Core
            Reporter: Ramin Gharib
             Fix For: 2.4.0


{{Variant.getField}} decodes every metadata key it compares into a new 
{{String}}:

{code:java}
// BinaryVariant.getFieldByKey, linear search for objects below 32 fields
if (key.equals(getMetadataKey(metadata, id))) {
{code}

{{v['a']}} in SQL calls {{getField}} once per record. One lookup in a 13-key 
object can create 13 throwaway strings.

h3. Proposal

For objects below {{BINARY_SEARCH_THRESHOLD}} fields, encode the wanted key to 
UTF-8 once. Compare it with the key bytes in the metadata dictionary. The 
builder stores keys as {{key.getBytes(UTF_8)}}, so the lookup encodes the same 
way.

The binary search for larger objects stays as it is. It depends on the order in 
which the builder sorts keys. That order is {{String.compareTo}}, not the UTF-8 
byte order the Parquet Variant spec asks for. Fixing the order is a separate 
ticket.

JMH on JDK 17, 4 lookups per row of 13 keys:

|| ||master||patch||
|time per row|285 ns|132 ns|
|allocated per row|1368 B|296 B|

h3. Behavior changes below the threshold

||Lookup||master||patch||
|{{getField("a\uD800")}} on a field written with that key|null|found|
|{{getField("\uFFFD")}} on a key whose bytes are not valid UTF-8|found|null|

Flink never writes keys that are not valid UTF-8. Two distinct malformed keys 
already decoded to the same name.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to