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

Jean-Noël Rouvignac
27.23.2015 9a216edaba16b28f240832cbbb25a5e6b367ac86
OPENDJ-2476 Purge of file-based changelog is very slow and the changelog size is growing

Monitoring shows generating the cookies makes up for a big part of the processing time.
2 factors make this slow:
* using String.format() which ends up always parsing the same format string
* continuously repeating toString()

Here is how this commit fixes these problems:
* used StringBuilder + Long/Integer.toHexString() + custom padding
* Created several toString(StringBuffer) methods and chained them
3 files modified
118 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/replication/common/CSN.java 59 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/common/MultiDomainServerState.java 24 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/common/ServerState.java 35 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/replication/common/CSN.java
@@ -181,7 +181,6 @@
    return serverId;
  }
  /** {@inheritDoc} */
  @Override
  public boolean equals(Object obj)
  {
@@ -201,7 +200,6 @@
    }
  }
  /** {@inheritDoc} */
  @Override
  public int hashCode()
  {
@@ -219,8 +217,9 @@
   */
  public ByteString toByteString()
  {
    return toByteString(new ByteStringBuilder(BYTE_ENCODING_LENGTH))
        .toByteString();
    final ByteStringBuilder builder = new ByteStringBuilder(BYTE_ENCODING_LENGTH);
    toByteString(builder);
    return builder.toByteString();
  }
  /**
@@ -231,12 +230,11 @@
   *
   * @param builder
   *          The byte string builder.
   * @return The byte string builder containing the encoded CSN.
   * @see #valueOf(ByteSequence)
   */
  public ByteStringBuilder toByteString(ByteStringBuilder builder)
  public void toByteString(ByteStringBuilder builder)
  {
    return builder.appendLong(timeStamp).appendShort(serverId & 0xffff).appendInt(seqnum);
    builder.appendLong(timeStamp).appendShort(serverId & 0xffff).appendInt(seqnum);
  }
  /**
@@ -250,7 +248,34 @@
  @Override
  public String toString()
  {
    return String.format("%016x%04x%08x", timeStamp, serverId, seqnum);
    final StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends the text representation of this {@link CSN} into the provided StringBuilder.
   * <p>
   * NOTE: this representation must not be modified otherwise interop with
   * earlier protocol versions will be broken.
   *
   * @param buffer the StringBuilder where to output the CSN text representation
   */
  void toString(final StringBuilder buffer)
  {
    leftPadWithZeros(buffer, 16, Long.toHexString(timeStamp));
    leftPadWithZeros(buffer, 4, Integer.toHexString(serverId));
    leftPadWithZeros(buffer, 8, Integer.toHexString(seqnum));
  }
  private void leftPadWithZeros(StringBuilder buffer, int nbChars, String toAppend)
  {
    final int padding = nbChars - toAppend.length();
    for (int i = 0; i < padding; i++)
    {
      buffer.append('0');
    }
    buffer.append(toAppend);
  }
  /**
@@ -260,11 +285,19 @@
   */
  public String toStringUI()
  {
    Date date = new Date(timeStamp);
    return String.format(
        "%016x%04x%08x (sid=%d,tsd=%s,ts=%d,seqnum=%d)",
        timeStamp, serverId, seqnum,
        serverId, date.toString(), timeStamp, seqnum);
    final StringBuilder buffer = new StringBuilder();
    toStringUI(buffer);
    return buffer.toString();
  }
  private void toStringUI(final StringBuilder buffer)
  {
    toString(buffer);
    buffer.append(" (sid=").append(serverId)
          .append(",tsd=").append(new Date(timeStamp))
          .append(",ts=").append(timeStamp)
          .append(",seqnum=").append(seqnum)
          .append(")");
  }
  /**
opendj-server-legacy/src/main/java/org/opends/server/replication/common/MultiDomainServerState.java
@@ -211,16 +211,9 @@
  @Override
  public String toString()
  {
    final StringBuilder res = new StringBuilder();
    if (list != null && !list.isEmpty())
    {
      for (Entry<DN, ServerState> entry : list.entrySet())
      {
        res.append(entry.getKey()).append(":")
           .append(entry.getValue()).append(";");
      }
    }
    return res.toString();
    final StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
@@ -229,7 +222,16 @@
   */
  public void toString(StringBuilder buffer)
  {
    buffer.append(this);
    if (list != null && !list.isEmpty())
    {
      for (Entry<DN, ServerState> entry : list.entrySet())
      {
        entry.getKey().toString(buffer);
        buffer.append(":");
        entry.getValue().toString(buffer);
        buffer.append(";");
      }
    }
  }
  /**
opendj-server-legacy/src/main/java/org/opends/server/replication/common/ServerState.java
@@ -27,14 +27,21 @@
package org.opends.server.replication.common;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.forgerock.opendj.io.ASN1Writer;
import org.opends.server.replication.protocol.ProtocolVersion;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.util.Utils;
import org.opends.server.replication.protocol.ProtocolVersion;
/**
 * This class is used to associate serverIds with {@link CSN}s.
@@ -269,7 +276,27 @@
  @Override
  public String toString()
  {
    return Utils.joinAsString(" ", serverIdToCSN.values());
    final StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }
  /**
   * Appends the text representation of ServerState.
   * @param buffer The buffer to which the information should be appended.
   */
  void toString(final StringBuilder buffer)
  {
    boolean first = true;
    for (CSN csn : serverIdToCSN.values())
    {
      if (!first)
      {
        buffer.append(" ");
      }
      csn.toString(buffer);
      first = false;
    }
  }
  /**