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

Fabio Pistolesi
12.18.2015 b863e237d8a0ba39af6cb61340db95cfc5166237
OPENDJ-2108 CR-7212 Some indexes are evaluated as indexed but should be not-indexed.

Running a search query with debugsearchindex, should tell how the server uses indexes.
Some optimisations change the index type actually used to perform, so that even if the attribute or the type are not indexed,
we may revert to an indexed search but we report the original search attribute and index type.
4 files modified
74 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java 41 ●●●● 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 14 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQueryFactoryImpl.java 15 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/AttributeIndex.java
@@ -498,12 +498,13 @@
      StringBuilder debugBuffer, BackendMonitor monitor)
  {
    LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
    EntryIDSet results = indexQuery.evaluate(debugMessage);
    StringBuilder indexNameOut = debugBuffer == null ? null : new StringBuilder();
    EntryIDSet results = indexQuery.evaluate(debugMessage, indexNameOut);
    if (debugBuffer != null)
    {
      debugBuffer.append("[INDEX:").append(config.getAttribute().getNameOrOID())
        .append(".").append(indexName).append("]");
      appendDebugIndexInformation(debugBuffer, indexName);
      appendDebugUnindexedInformation(debugBuffer, indexNameOut);
    }
    if (monitor.isFilterUseEnabled())
@@ -521,6 +522,27 @@
  }
  /**
   * Appends additional traces to {@code debugsearchindex} when a filter successfully used
   * an auxiliary index type during index query.
   *
   * @param debugBuffer the current debugsearchindex buffer
   * @param indexNameOut the name of the index type
   */
  private void appendDebugUnindexedInformation(StringBuilder debugBuffer, StringBuilder indexNameOut)
  {
    if (indexNameOut.length() > 0)
    {
      debugBuffer.append(newUndefinedSet().toString());
      appendDebugIndexInformation(debugBuffer, indexNameOut.toString());
    }
  }
  private void appendDebugIndexInformation(final StringBuilder debugBuffer, final String infos)
  {
    debugBuffer.append("[INDEX:").append(config.getAttribute().getNameOrOID()).append(".").append(infos).append("]");
  }
  /**
   * Retrieve the entry IDs that might match two filters that restrict a value
   * to both a lower bound and an upper bound.
   *
@@ -881,11 +903,16 @@
        monitor.updateStats(filter,
            INFO_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(matchRuleOID, config.getAttribute().getNameOrOID()));
      }
      return IndexQuery.createNullIndexQuery().evaluate(null);
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
    }
    try
    {
      final IndexQuery indexQuery = rule.getAssertion(filter.getAssertionValue()).createIndexQuery(indexQueryFactory);
      LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
      StringBuilder indexNameOut = debugBuffer == null ? null : new StringBuilder();
      EntryIDSet results = indexQuery.evaluate(debugMessage, indexNameOut);
      if (debugBuffer != null)
      {
        debugBuffer.append("[INDEX:");
@@ -897,11 +924,9 @@
              .append(indexer.getIndexID());
        }
        debugBuffer.append("]");
        appendDebugUnindexedInformation(debugBuffer, indexNameOut);
      }
      final IndexQuery indexQuery = rule.getAssertion(filter.getAssertionValue()).createIndexQuery(indexQueryFactory);
      LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
      EntryIDSet results = indexQuery.evaluate(debugMessage);
      if (monitor.isFilterUseEnabled())
      {
        if (results.isDefined())
@@ -918,7 +943,7 @@
    catch (DecodeException e)
    {
      logger.traceException(e);
      return IndexQuery.createNullIndexQuery().evaluate(null);
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
    }
  }
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexFilter.java
@@ -351,7 +351,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);
      return IndexQuery.createNullIndexQuery().evaluate(null, null);
    }
    AttributeIndex attributeIndex = entryContainer.getAttributeIndex(extensibleFilter.getAttributeType());
@@ -360,7 +360,7 @@
      final IndexQueryFactoryImpl indexQueryFactory = new IndexQueryFactoryImpl(txn, attributeIndex);
      return attributeIndex.evaluateExtensibleFilter(indexQueryFactory, extensibleFilter, buffer, monitor);
    }
    return IndexQuery.createNullIndexQuery().evaluate(null);
    return IndexQuery.createNullIndexQuery().evaluate(null, null);
  }
  private void appendToDebugBuffer(String content)
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQuery.java
@@ -52,9 +52,11 @@
   * @param debugMessage If not null, diagnostic message will be written
   *                      which will help to determine why the returned
   *                      EntryIDSet is not defined.
   * @param indexNameOut If not null, output parameter for the name of the index type actually used to return
   *                      index results.
   * @return The non null EntryIDSet as a result of evaluating this query
   */
  public abstract EntryIDSet evaluate(LocalizableMessageBuilder debugMessage);
  public abstract EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut);
  /**
   * Creates an IntersectionIndexQuery object from a collection of
@@ -101,7 +103,7 @@
  private static final class NullIndexQuery extends IndexQuery
  {
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      return newUndefinedSet();
    }
@@ -134,12 +136,12 @@
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newUndefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.retainAll(query.evaluate(debugMessage));
        entryIDs.retainAll(query.evaluate(debugMessage, indexNameOut));
        if (isBelowFilterThreshold(entryIDs))
        {
          break;
@@ -173,12 +175,12 @@
    }
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
    {
      final EntryIDSet entryIDs = newDefinedSet();
      for (IndexQuery query : subIndexQueries)
      {
        entryIDs.addAll(query.evaluate(debugMessage));
        entryIDs.addAll(query.evaluate(debugMessage, indexNameOut));
        if (entryIDs.isDefined() && entryIDs.size() >= CURSOR_ENTRY_LIMIT)
        {
          break;
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/IndexQueryFactoryImpl.java
@@ -38,6 +38,7 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
import org.forgerock.opendj.ldap.spi.IndexingOptions;
import org.opends.server.backends.pluggable.AttributeIndex.IndexFilterType;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
@@ -77,7 +78,7 @@
    return new IndexQuery()
      {
        @Override
        public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
        public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
        {
          // Read the tree and get Record for the key.
          // Select the right index to be used.
@@ -89,7 +90,7 @@
              debugMessage.append(INFO_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID,
                  attributeIndex.getAttributeType().getNameOrOID()));
            }
            return createMatchAllQuery().evaluate(debugMessage);
            return createMatchAllQuery().evaluate(debugMessage, indexNameOut);
          }
          final EntryIDSet entrySet = index.get(txn, key);
@@ -116,7 +117,7 @@
    return new IndexQuery()
    {
      @Override
      public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
      public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
      {
        final Index index = attributeIndex.getNameToIndexes().get(indexID);
        if (index == null)
@@ -126,7 +127,7 @@
            debugMessage.append(INFO_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID,
                  attributeIndex.getAttributeType().getNameOrOID()));
          }
          return createMatchAllQuery().evaluate(debugMessage);
          return createMatchAllQuery().evaluate(debugMessage, indexNameOut);
        }
        final EntryIDSet entrySet = readRange(index, txn, lowerBound, upperBound, includeLowerBound, includeUpperBound);
@@ -263,7 +264,7 @@
    return new IndexQuery()
      {
        @Override
        public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
        public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage, StringBuilder indexNameOut)
        {
          final String indexID = PRESENCE_INDEX_KEY;
          final Index index = attributeIndex.getNameToIndexes().get(indexID);
@@ -282,6 +283,10 @@
          {
            updateStatsUndefinedResults(debugMessage, index);
          }
          if (indexNameOut != null)
          {
            indexNameOut.append(IndexFilterType.PRESENCE.toString());
          }
          return entrySet;
        }