mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
15.33.2007 8633e780ffe89c5cf5453d40b9b65fd3fd1ef17f
Performance improvements to server-side admin framework.

The strongly typed server-side APIs now retrieve and cache their property values during construction so that subsequent calls to property getters no longer have to repeatedly access the underlying ServerManagedObject. This avoids having to repeatedly perform hash-table look-ups in the ServerManagedObject and, in the case of single-valued properties, temporary construction of iterators.

I have also modified the ServerManagedObject#getPropertyValues() method to return an UnmodifiableSortedSet rather than a defensive copy and updated the javadoc in the generated server-side getters to reflect that the returned set is unmodifiable.
3 files modified
127 ■■■■ changed files
opendj-sdk/opends/resource/admin/metaMO.xsl 81 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/property-types.xsl 34 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java 12 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -86,7 +86,8 @@
    <xsl:for-each
      select="$this-local-properties[adm:syntax/adm:enumeration and not(adm:profile[@name='preprocessor']/adm:first-defined-in)]">
      <xsl:sort select="@name" />
      <xsl:if test="not(adm:profile[@name='preprocessor']/admpp:first-defined-in)">
      <xsl:if
        test="not(adm:profile[@name='preprocessor']/admpp:first-defined-in)">
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
        <xsl:text>&#xa;</xsl:text>
@@ -368,7 +369,8 @@
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:call-template name="generate-property-getter-implementation">
      <xsl:call-template
        name="generate-property-getter-implementation">
        <xsl:with-param name="interface" select="'client'" />
      </xsl:call-template>
      <xsl:text>&#xa;</xsl:text>
@@ -455,6 +457,50 @@
      select="concat('    // Private implementation.&#xa;',
                     '    private ServerManagedObject&lt;? extends ', $this-java-class, 'Cfg&gt; impl;&#xa;')" />
    <!--
      Private members for each property.
    -->
    <xsl:for-each select="$this-all-properties">
      <xsl:sort select="@name" />
      <xsl:text>&#xa;</xsl:text>
      <xsl:value-of
        select="concat('    // The value of the &quot;', @name, '&quot; property.&#xa;')" />
      <xsl:value-of select="'    private final '" />
      <xsl:choose>
        <xsl:when test="string(@multi-valued) != 'true'">
          <xsl:choose>
            <xsl:when test="adm:default-behavior/adm:defined">
              <!--
                The property is guaranteed to contain a value since there is a
                well-defined default value.
              -->
              <xsl:call-template
                name="get-property-java-primitive-type" />
            </xsl:when>
            <xsl:when test="@mandatory = 'true'">
              <!--
                The property is guaranteed to contain a value in the server interface.
              -->
              <xsl:call-template
                name="get-property-java-primitive-type" />
            </xsl:when>
            <xsl:otherwise>
              <xsl:call-template name="get-property-java-type" />
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'SortedSet&lt;'" />
          <xsl:call-template name="get-property-java-type" />
          <xsl:value-of select="'&gt;'" />
        </xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="' p'" />
      <xsl:call-template name="name-to-java">
        <xsl:with-param name="value" select="@name" />
      </xsl:call-template>
      <xsl:value-of select="';&#xa;'" />
    </xsl:for-each>
    <!--
      Private constructor.
    -->
    <xsl:text>&#xa;</xsl:text>
@@ -465,8 +511,28 @@
                     '    private ',
                     $this-java-class,
                     'CfgServerImpl(ServerManagedObject&lt;? extends ', $this-java-class, 'Cfg&gt; impl) {&#xa;',
                     '      this.impl = impl;&#xa;',
                     '    }&#xa;')" />
                     '      this.impl = impl;&#xa;')" />
    <xsl:for-each select="$this-all-properties">
      <xsl:sort select="@name" />
      <xsl:variable name="java-prop-name">
        <xsl:call-template name="name-to-java">
          <xsl:with-param name="value" select="@name" />
        </xsl:call-template>
      </xsl:variable>
      <xsl:value-of
        select="concat('      this.p', $java-prop-name, ' = ')" />
      <xsl:choose>
        <xsl:when test="string(@multi-valued) != 'true'">
          <xsl:value-of
            select="concat('impl.getPropertyValue(INSTANCE.get', $java-prop-name , 'PropertyDefinition());&#xa;')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of
            select="concat('impl.getPropertyValues(INSTANCE.get', $java-prop-name , 'PropertyDefinition());&#xa;')" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
    <xsl:value-of select="'    }&#xa;'" />
    <!--
      Generate all the change listener methods - one for each managed
      object in the hierarchy.
@@ -478,14 +544,15 @@
      <xsl:call-template name="generate-change-listener" />
    </xsl:if>
    <!--
      Getters/Setters for all properties.
      Getters for all properties.
    -->
    <xsl:for-each select="$this-all-properties">
      <xsl:sort select="@name" />
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:call-template name="generate-property-getter-implementation">
      <xsl:call-template
        name="generate-property-getter-implementation">
        <xsl:with-param name="interface" select="'server'" />
      </xsl:call-template>
    </xsl:for-each>
@@ -716,7 +783,7 @@
      select="concat('      PD_', $java-prop-name, ' = builder.getInstance();&#xa;')" />
    <xsl:value-of
      select="concat('      INSTANCE.registerPropertyDefinition(PD_', $java-prop-name, ');&#xa;')" />
    <xsl:call-template name="get-property-definition-post-ctor"/>
    <xsl:call-template name="get-property-definition-post-ctor" />
    <xsl:value-of select="'  }&#xa;'" />
  </xsl:template>
  <!--
opendj-sdk/opends/resource/admin/property-types.xsl
@@ -351,10 +351,20 @@
        </xsl:choose>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of
          select="concat('   *&#xa;',
        <xsl:choose>
          <xsl:when test="$interface='server'">
            <xsl:value-of
              select="concat('   *&#xa;',
                     '   * @return Returns an unmodifiable set containing the values of the &quot;', $name,'&quot; property.&#xa;',
                     '   */&#xa;')" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of
              select="concat('   *&#xa;',
                     '   * @return Returns the values of the &quot;', $name,'&quot; property.&#xa;',
                     '   */&#xa;')" />
          </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="'  SortedSet&lt;'" />
        <xsl:call-template name="get-property-java-type" />
        <xsl:value-of select="'&gt;'" />
@@ -435,21 +445,31 @@
      </xsl:otherwise>
    </xsl:choose>
    <xsl:choose>
      <xsl:when test="string(@multi-valued) != 'true'">
      <xsl:when test="$interface='server'">
        <xsl:value-of
          select="concat($java-prop-name, '() {&#xa;',
                                     '      return p', $java-prop-name , ';&#xa;' ,
                                     '    }&#xa;')" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="string(@multi-valued) != 'true'">
            <xsl:value-of
              select="concat($java-prop-name, '() {&#xa;',
                                     '      return impl.getPropertyValue',
                                     '(INSTANCE.get', $java-prop-name ,
                                     'PropertyDefinition());&#xa;' ,
                                     '    }&#xa;')" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of
          select="concat($java-prop-name, '() {&#xa;',
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of
              select="concat($java-prop-name, '() {&#xa;',
                                     '      return impl.getPropertyValues',
                                     '(INSTANCE.get', $java-prop-name ,
                                     'PropertyDefinition());&#xa;' ,
                                     '    }&#xa;')" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -33,12 +33,12 @@
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.opends.messages.AdminMessages;
import org.opends.messages.Message;
@@ -411,10 +411,10 @@
   *          The type of the property to be retrieved.
   * @param d
   *          The property to be retrieved.
   * @return Returns a newly allocated set containing a copy of the
   *         property's effective values. An empty set indicates that
   *         the property has no default values defined and any
   *         default behavior is applicable.
   * @return Returns an unmodifiable set containing the property's
   *         effective values. An empty set indicates that the
   *         property has no default values defined and any default
   *         behavior is applicable.
   * @throws IllegalArgumentException
   *           If the property definition is not associated with this
   *           managed object's definition.
@@ -425,7 +425,7 @@
    if (!properties.containsKey(d)) {
      throw new IllegalArgumentException("Unknown property " + d.getName());
    }
    return new TreeSet<T>((SortedSet<T>) properties.get(d));
    return Collections.unmodifiableSortedSet((SortedSet<T>) properties.get(d));
  }