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

Jean-Noël Rouvignac
07.43.2015 88f8db26c1a4389ea8ddcd5679f433446d0a55f3
OPENDJ-1852 Fix feature envy between AttributeIndex and Index* classes

IndexQuery.java:
Changed to be an interface
Moved all factory methods and inner classes to IndexQueryFactoryImpl
4 files modified
282 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java 4 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexFilter.java 4 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQuery.java 155 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQueryFactoryImpl.java 119 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java
@@ -907,7 +907,7 @@
        monitor.updateStats(filter,
            INFO_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(matchRuleOID, config.getAttribute().getNameOrOID()));
      }
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
      return IndexQueryFactoryImpl.createNullIndexQuery().evaluate(null, null);
    }
    try
@@ -947,7 +947,7 @@
    catch (DecodeException e)
    {
      logger.traceException(e);
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
      return IndexQueryFactoryImpl.createNullIndexQuery().evaluate(null, null);
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexFilter.java
@@ -347,7 +347,7 @@
      // This will always be unindexed since the filter potentially matches
      // entries containing the specified attribute type as well as any entry
      // containing the attribute in its DN as part of a superior RDN.
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
      return IndexQueryFactoryImpl.createNullIndexQuery().evaluate(null, null);
    }
    AttributeIndex attributeIndex = entryContainer.getAttributeIndex(extensibleFilter.getAttributeType());
@@ -356,7 +356,7 @@
      final IndexQueryFactoryImpl indexQueryFactory = new IndexQueryFactoryImpl(txn, attributeIndex);
      return attributeIndex.evaluateExtensibleFilter(indexQueryFactory, extensibleFilter, buffer, monitor);
    }
    return IndexQuery.createNullIndexQuery().evaluate(null, null);
    return IndexQueryFactoryImpl.createNullIndexQuery().evaluate(null, null);
  }
  private void appendToDebugBuffer(String content)
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQuery.java
@@ -26,24 +26,12 @@
 */
package org.opends.server.backends.pluggable;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.IndexFilter.*;
import java.util.Collection;
import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.util.Utils;
/** This class represents a Backend Query. */
@org.opends.server.types.PublicAPI(
    stability = org.opends.server.types.StabilityLevel.VOLATILE,
    mayInstantiate = false,
    mayExtend = true,
    mayInvoke = false)
abstract class IndexQuery
/** This interface represents a Backend Query. */
// @FunctionalInterface
interface IndexQuery
{
  private static final String SEPARATOR = "\n  ";
  /**
   * Evaluates the index query and returns the EntryIDSet.
   *
@@ -54,140 +42,5 @@
   *                      index results.
   * @return The non null EntryIDSet as a result of evaluating this query
   */
  public abstract EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut);
  /**
   * Creates an IntersectionIndexQuery object from a collection of
   * IndexQuery objects.
   *
   * @param subIndexQueries
   *          A collection of IndexQuery objects.
   * @return An IntersectionIndexQuery object.
   */
  static IndexQuery createIntersectionIndexQuery(Collection<IndexQuery> subIndexQueries)
  {
    return new IntersectionIndexQuery(subIndexQueries);
  }
  /**
   * Creates a union IndexQuery object from a collection of IndexQuery
   * objects.
   *
   * @param subIndexQueries
   *          Collection of IndexQuery objects.
   * @return A UnionIndexQuery object.
   */
  static IndexQuery createUnionIndexQuery(Collection<IndexQuery> subIndexQueries)
  {
    return new UnionIndexQuery(subIndexQueries);
  }
  /**
   * Creates an empty IndexQuery object.
   *
   * @return A NullIndexQuery object.
   */
  static IndexQuery createNullIndexQuery()
  {
    return new NullIndexQuery();
  }
  /**
   * This class creates a Null IndexQuery. It is used when there is no
   * record in the index. It may also be used when the index contains
   * all the records but an empty EntryIDSet should be returned as part
   * of the optimization.
   */
  private static final class NullIndexQuery extends IndexQuery
  {
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      return newUndefinedSet();
    }
    @Override
    public String toString()
    {
      return "Null";
    }
  }
  /** This class creates an intersection IndexQuery from a collection of IndexQuery objects. */
  private static final class IntersectionIndexQuery extends IndexQuery
  {
    /** Collection of IndexQuery objects. */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of IntersectionIndexQuery.
     *
     * @param subIndexQueries
     *          Collection of IndexQuery objects.
     */
    private IntersectionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newUndefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.retainAll(query.evaluate(debugMessage, indexNameOut));
        if (isBelowFilterThreshold(entryIDs))
        {
          break;
        }
      }
      return entryIDs;
    }
    @Override
    public String toString()
    {
      return "Intersection(" + SEPARATOR + Utils.joinAsString(SEPARATOR, subIndexQueries) + ")";
    }
  }
  /** This class creates a union of IndexQuery objects. */
  private static final class UnionIndexQuery extends IndexQuery
  {
    /** Collection containing IndexQuery objects. */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of UnionIndexQuery.
     *
     * @param subIndexQueries
     *          The Collection of IndexQuery objects.
     */
    private UnionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newDefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.addAll(query.evaluate(debugMessage, indexNameOut));
        if (entryIDs.isDefined() && entryIDs.size() >= CURSOR_ENTRY_LIMIT)
        {
          break;
        }
      }
      return entryIDs;
    }
    @Override
    public String toString()
    {
      return "Union(" + SEPARATOR + Utils.joinAsString(SEPARATOR, subIndexQueries) + ")";
    }
  }
  EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut);
}
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQueryFactoryImpl.java
@@ -27,8 +27,8 @@
package org.opends.server.backends.pluggable;
import static org.opends.messages.BackendMessages.*;
import static org.opends.server.backends.pluggable.EntryIDSet.newUndefinedSet;
import static org.opends.server.backends.pluggable.EntryIDSet.newUndefinedSetWithKey;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.IndexFilter.*;
import java.util.ArrayList;
import java.util.Collection;
@@ -39,6 +39,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
import org.forgerock.opendj.ldap.spi.IndexingOptions;
import org.forgerock.util.Utils;
import org.opends.server.backends.pluggable.AttributeIndex.IndexFilterType;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
@@ -50,9 +51,109 @@
 */
final class IndexQueryFactoryImpl implements IndexQueryFactory<IndexQuery>
{
  /**
   * This class creates a Null IndexQuery. It is used when there is no
   * record in the index. It may also be used when the index contains
   * all the records but an empty EntryIDSet should be returned as part
   * of the optimization.
   */
  private static final class NullIndexQuery implements IndexQuery
  {
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      return newUndefinedSet();
    }
    @Override
    public String toString()
    {
      return "Null";
    }
  }
  /** This class creates an intersection IndexQuery from a collection of IndexQuery objects. */
  private static final class IntersectionIndexQuery implements IndexQuery
  {
    /** Collection of IndexQuery objects. */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of IntersectionIndexQuery.
     *
     * @param subIndexQueries
     *          Collection of IndexQuery objects.
     */
    private IntersectionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newUndefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.retainAll(query.evaluate(debugMessage, indexNameOut));
        if (isBelowFilterThreshold(entryIDs))
        {
          break;
        }
      }
      return entryIDs;
    }
    @Override
    public String toString()
    {
      return "Intersection(" + SEPARATOR + Utils.joinAsString(SEPARATOR, subIndexQueries) + ")";
    }
  }
  /** This class creates a union of IndexQuery objects. */
  private static final class UnionIndexQuery implements IndexQuery
  {
    /** Collection containing IndexQuery objects. */
    private final Collection<IndexQuery> subIndexQueries;
    /**
     * Creates an instance of UnionIndexQuery.
     *
     * @param subIndexQueries
     *          The Collection of IndexQuery objects.
     */
    private UnionIndexQuery(Collection<IndexQuery> subIndexQueries)
    {
      this.subIndexQueries = subIndexQueries;
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newDefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.addAll(query.evaluate(debugMessage, indexNameOut));
        if (entryIDs.isDefined() && entryIDs.size() >= CURSOR_ENTRY_LIMIT)
        {
          break;
        }
      }
      return entryIDs;
    }
    @Override
    public String toString()
    {
      return "Union(" + SEPARATOR + Utils.joinAsString(SEPARATOR, subIndexQueries) + ")";
    }
  }
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  private static final String PRESENCE_INDEX_KEY = "presence";
  private static final String SEPARATOR = "\n  ";
  private final ReadableTransaction txn;
  /** The Map containing the string type identifier and the corresponding index. */
@@ -241,13 +342,13 @@
  @Override
  public IndexQuery createIntersectionQuery(Collection<IndexQuery> subqueries)
  {
    return IndexQuery.createIntersectionIndexQuery(subqueries);
    return new IntersectionIndexQuery(subqueries);
  }
  @Override
  public IndexQuery createUnionQuery(Collection<IndexQuery> subqueries)
  {
    return IndexQuery.createUnionIndexQuery(subqueries);
    return new UnionIndexQuery(subqueries);
  }
  /**
@@ -313,4 +414,14 @@
  {
    return attributeIndex.getIndexingOptions();
  }
  /**
   * Creates an empty IndexQuery object.
   *
   * @return A NullIndexQuery object.
   */
  static IndexQuery createNullIndexQuery()
  {
    return new NullIndexQuery();
  }
}