<!-- 
RSS generated by JIRA (8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d) at Wed Feb 07 20:54:57 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>OpenDaylight JIRA</title>
    <link>https://jira.opendaylight.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>8.20.10</version>
        <build-number>820010</build-number>
        <build-date>22-06-2022</build-date>
    </build-info>


<item>
            <title>[YANGTOOLS-1020] Add runtime-generated Immutable maps</title>
                <link>https://jira.opendaylight.org/browse/YANGTOOLS-1020</link>
                <project id="10188" key="YANGTOOLS">yangtools</project>
                    <description>&lt;p&gt;Heap dump analysis of an OFP-related use case is showing that even though we are using ImmutableOffsetMaps to hold children, those maps still account for 2.4M (10%) objects holding 55MiB (9%) shallow memory, with additional 55MiB (9%) retained by their Object[]s.&lt;/p&gt;

&lt;p&gt;The Object array size ranges from 2 to 12 elements, which means they have 60% to 20% overhead.&lt;/p&gt;

&lt;p&gt;We should be able to bring these overheads down by application of runtime code generation, where we&apos;d generate the equivalent of ImmutableOffsetMap.Unordered, where the values are stored directly in fields of the generated class. This would eliminate the need for Object[]s &#8211; i.e. 7% of heap occupancy.&lt;/p&gt;

&lt;p&gt;Code generation should be based on Byte-Buddy, i.e. generate bytecode.&lt;/p&gt;

&lt;p&gt;The implementation should assume NodeIdentifier addressing, i.e. the keys are strictly based on QNames. These should be destructured during internal dispatch, so that we first compare QNameModule portion (which is typically unique, but there may be others, i.e. in case of augment), then we should perform a simple switch() on localName.&lt;/p&gt;

&lt;p&gt;The bytecode should be roughly equivalent to:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
&lt;span class=&quot;code-comment&quot;&gt;// Hand-coded base class
&lt;/span&gt;&lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;class &lt;/span&gt;AbstractNodeIdentifierMap&amp;lt;V&amp;gt; &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; AbstractMap&amp;lt;NodeIdentifier, V&amp;gt; &lt;span class=&quot;code-keyword&quot;&gt;implements&lt;/span&gt; Immutable {
  @Override
  &lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; V get(&lt;span class=&quot;code-object&quot;&gt;Object&lt;/span&gt; obj) {
    &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; obj &lt;span class=&quot;code-keyword&quot;&gt;instanceof&lt;/span&gt; NodeIdentifier nid ? get(nid.getType()) : &lt;span class=&quot;code-keyword&quot;&gt;null&lt;/span&gt;;
  }

  &lt;span class=&quot;code-keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;abstract&lt;/span&gt; V get(QName qname);
}

&lt;span class=&quot;code-comment&quot;&gt;// Generated
&lt;/span&gt;&lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;class &lt;/span&gt;NodeIdenfierMapXXYYZZ&amp;lt;V&amp;gt; &lt;span class=&quot;code-keyword&quot;&gt;extends&lt;/span&gt; AbstractNodeIdentifierMap&amp;lt;V&amp;gt; {
  &lt;span class=&quot;code-comment&quot;&gt;// ... &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; each child QNameModule
&lt;/span&gt;  &lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; QNameModule MODULE0;
  &lt;span class=&quot;code-comment&quot;&gt;// ... also we may need constants &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; QNames &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; things like entrySet(), keySet(), etc.
&lt;/span&gt;  
  &lt;span class=&quot;code-comment&quot;&gt;// actually something reasonably-derived from QName?
&lt;/span&gt; &#160;&lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; V v0_0;
  &lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; V v0_1;

  @Override
  &lt;span class=&quot;code-keyword&quot;&gt;protected&lt;/span&gt; V get(QName qnamej) {
    &lt;span class=&quot;code-keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;var&lt;/span&gt; module = qname.getModule();
    &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (MODULE0.equals(module)) {
        &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; get0(qname.getLocalName());
    }
    &lt;span class=&quot;code-comment&quot;&gt;// &lt;span class=&quot;code-keyword&quot;&gt;else&lt;/span&gt; ... &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; we have more QNameModule
&lt;/span&gt;
    &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;null&lt;/span&gt;;
  }

  &lt;span class=&quot;code-comment&quot;&gt;// peeled &lt;span class=&quot;code-keyword&quot;&gt;for&lt;/span&gt; each QNameModule
&lt;/span&gt;  &lt;span class=&quot;code-keyword&quot;&gt;private&lt;/span&gt; V get0(&lt;span class=&quot;code-object&quot;&gt;String&lt;/span&gt; localName) {
    &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;code-keyword&quot;&gt;switch&lt;/span&gt; (localName) {
      &lt;span class=&quot;code-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;code-quote&quot;&gt;&quot;some-name&quot;&lt;/span&gt; -&amp;gt; field0_0;
      &lt;span class=&quot;code-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;code-quote&quot;&gt;&quot;other-name&quot;&lt;/span&gt; -&amp;gt; field0_1;
      &lt;span class=&quot;code-keyword&quot;&gt;default&lt;/span&gt; -&amp;gt; &lt;span class=&quot;code-keyword&quot;&gt;null&lt;/span&gt;;
    }
  }
}
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</description>
                <environment></environment>
        <key id="31922">YANGTOOLS-1020</key>
            <summary>Add runtime-generated Immutable maps</summary>
                <type id="10103" iconUrl="https://jira.opendaylight.org/secure/viewavatar?size=xsmall&amp;avatarId=10311&amp;avatarType=issuetype">New Feature</type>
                                            <priority id="3" iconUrl="https://jira.opendaylight.org/images/icons/priorities/major.svg">Medium</priority>
                        <status id="10003" iconUrl="https://jira.opendaylight.org/images/icons/status_generic.gif" description="">Confirmed</status>
                    <statusCategory id="2" key="new" colorName="blue-gray"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="rovarga">Robert Varga</reporter>
                        <labels>
                    </labels>
                <created>Tue, 27 Aug 2019 08:46:03 +0000</created>
                <updated>Fri, 5 Jan 2024 14:57:25 +0000</updated>
                                                            <fixVersion>14.0.0</fixVersion>
                                    <component>data-impl</component>
                        <due></due>
                            <votes>0</votes>
                                    <watches>1</watches>
                                                                                                                <comments>
                            <comment id="67196" author="rovarga" created="Tue, 27 Aug 2019 08:55:41 +0000"  >&lt;p&gt;Note that these maps will need to implement efficient expansion/contraction via ModifiableMapPhase, so they can re-done during DataTree operations.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10000">
                    <name>Blocks</name>
                                            <outwardlinks description="blocks">
                                        <issuelink>
            <issuekey id="31923">YANGTOOLS-1021</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10003">
                    <name>Relates</name>
                                            <outwardlinks description="relates to">
                                        <issuelink>
            <issuekey id="22910">YANGTOOLS-490</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                            <customfield id="customfield_11400" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10000" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|i03oqv:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                </customfields>
    </item>
</channel>
</rss>