[YANGTOOLS-999] Rework NodeIdentifierWithPredicates Created: 30/May/19  Updated: 10/Apr/22  Resolved: 03/Sep/19

Status: Resolved
Project: yangtools
Component/s: None
Affects Version/s: None
Fix Version/s: 4.0.0

Type: Improvement Priority: Medium
Reporter: Robert Varga Assignee: Robert Varga
Resolution: Done Votes: 0
Labels: None
Σ Remaining Estimate: Not Specified Remaining Estimate: Not Specified
Σ Time Spent: Not Specified Time Spent: Not Specified
Σ Original Estimate: Not Specified Original Estimate: Not Specified

Sub-Tasks:
Key
Summary
Type
Status
Assignee
YANGTOOLS-1000 Deprecate public NodeIdentifierWithPr... Sub-task Resolved Robert Varga  

 Description   

Heap dump analysis from CONTROLLER-1898 shows that a typical openflow-related workload does not use more than one predicates anywhere – every one of the 1.4M objects has exactly one predicate.

This translates to 1.4M SharedSingletonMap instances, each costing a 24 bytes of storage – for a total of 34MiB, i.e. 3.7% of total memory footprint.

Current layout of NodeIdentifierWithPredicates results in 32/40 bytes per instance, with 7 bytes being wasted on alignment – hence we could inline the single key/value eliminating the need for retained secondary objects.

While straightforward, this will result in a Map, which will not retain a cached hashCode, hence is subject to trade-offs and further design.

Irrespective of that, we need to turn this class into a non-final value-based object, i.e. eliminate all of its public constructors, so that users are no longer strongly connected to its design.

 



 Comments   
Comment by Robert Varga [ 30/May/19 ]

With YANGTOOLS-1001 the math changes a bit, as the paddings are eliminated and NIWP is 24/32 bytes. With 24/32 bytes expended on SharedSingletonMap cost it boils down to a combined overhead of 48/64 bytes.

If we inline the single-predicate case, we will arrive at 32/40 bytes per instance size, with the weird problem of having to deal with the Map return. Ideally this implementation would also implement Map, but that would imply hashCode/equals contract, which we have to set differently. If we disregard hashcode caching for the singleton map, we can be giving out singleton instances on demand – which may or may not work out okay. Alternatively we can bloat a bit, keeping the hashCode for the map inside the NIWP instance (hence growing it to 32/48 bytes) and give out non-static maps which update the hashCode in NIWP.

Comment by Robert Varga [ 30/May/19 ]

Looking at the users, it seems the best option is to eliminate the Map return completely, or at least make it an optional secondary interface. Most callers are interested in the keyset/entryset/values and those could be supported without this conundrum. If we structure access correctly, we can also simplify equality contract, as zero-or-multiples would be handled by one class and singletons by another – thus also allowing for reasonable hashCode behavior.

Comment by Robert Varga [ 03/Sep/19 ]

https://git.opendaylight.org/gerrit/#/c/yangtools/+/82604/

Generated at Wed Feb 07 20:54:54 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.