Details
-
Improvement
-
Status: Confirmed
-
Resolution: Unresolved
-
None
-
None
-
None
-
None
-
Operating System: All
Platform: All
Description
Our current implementation of NormalizedNode interface is completely generic, without being tied to the SchemaContext in which those nodes are being used.
The implementation uses QName->child maps to hold child entities, which is quite wasteful, as those maps typically have the same key set or differ by non-presence of some children.
If a builder for a particular NormalizedNode were to know the SchemaNode of the entity being built, it could use that information to:
A) Validate the NormalizedNode as it is being built, which should be an optional feature, consisting of the following functionality:
A1) Checking for valid child QName
A2) Checking value type conformance (no Strings where Integer is expected)
A3) Checking value well-formedness (according to 'pattern' and 'range' statements)
A4) Checking/converting value to the canonical representation
A5) Checking NormalizedNode consistency (according to 'when' and similar statements) when .build() is called
B) Shared child keying
Given the finite-set of possible children, which we know from the SchemaNode, we can share the the information about which nodes are present across NormalizedNode instances in the global scope. This would lower the cost of keeping track of child values to:
- a Map<QName, Integer> shared across instances with the same keyset
- a per-instance Object[] containing child references
The Map can be implemented as an ImmutableMap, as the Integers involved will probably be coming from JVM's boxing cache.
C) (Optional) Lazy leaf children
When a child leaf is being looked up, we get provided with its identifier (and by extension, its node type). This means that structurally we need to only retain the fact that the child exists and its value. We then can instantiate a wrapper object around the value without explicitly storing it.
While this will potentially cause more object allocations to occur, our minimum memory footprint will go down, as we would not keep that wrapper object (of ~24 bytes) around.
Note that in some access patterns the JVM can use escape analysis to eliminate the allocation completely. This obviously depends on what the access pattern is and whether the producer uses some sort of value-caching (such as reusing a single global LeafNode instance).
Attachments
Issue Links
- relates to
-
YANGTOOLS-1019 Lazily-instantiated LeafNodes
-
- Resolved
-
-
YANGTOOLS-1020 Add runtime-generated Immutable maps
-
- Confirmed
-