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

Jean-Noel Rouvignac
04.26.2014 d8a5f7852b82181e5f9b9317e577d72372b968f7
OPENDJ-1308 Migrate schema support

Fix for regression introduced in r10576: changes to LocalDBIndexCfg.ds-cfg-index-entry-limit config would be ignored.
The fix consists in passing the value of this config down all the method calls.

Lots of code cleanup on AttributeIndex.


AttributeIndex.java:
In buildExtIndex(), newIndex(), newExtensibleIndex(), openNewIndex() added indexEntryLimit parameter.
In evaluateExtensibleFilter(), renamed variables to make the code look similar to evaluateIndexQuery().
Used nameToIndexes to remove a lot of redundant code + removed no longer necessary methods: open(), addEntry(), removeEntry(), modifyEntry(), addIfNotNull(), setTrusted(), setRebuildStatus().
Removed fields equalityIndex, presenceIndex, substringIndex, orderingIndex, approximateIndex.
Extracted method applyChangeToIndex().
Directly used IndexType enum.
Added a comment from Matt.

EntryContainer.java:
Consequence of the change to AttributeIndex, used AttributeIndex.getAllIndexes() to remove redundant code.

TestBackendImpl.java, TestVerifyJob.java:
Consequence of the change to AttributeIndex, used the getters instead.

IndexQueryFactoryImpl.java:
Extracted static method updateStatsUndefinedResults() to remove code duplication.

IndexQuery.java:
Fixed javadocs.



NotImplementedAssertion.java: REMOVED - unneeded after r10618

AbstractMatchingRule.java:
Consequence of removing NotImplementedAssertion

EqualityMatchingRule.java:
Removed unsued import.
8 files modified
1 files deleted
986 ■■■■■ changed files
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java 1 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java 678 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java 42 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java 28 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java 68 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java 82 ●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java 19 ●●●●● patch | view | raw | blame | history
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
@@ -183,13 +183,22 @@
      throws DecodeException
  {
    final ByteString assertionValue = normalizeAssertionValue(value);
    return new NotImplementedAssertion()
    return new Assertion()
    {
      /** {@inheritDoc} */
      @Override
      public ConditionResult matches(ByteSequence attributeValue)
      {
        return valuesMatch(attributeValue, assertionValue);
      }
      /** {@inheritDoc} */
      @Override
      public <T> T createIndexQuery(IndexQueryFactory<T> factory)
          throws DecodeException
      {
        throw new RuntimeException("Not implemented");
      }
    };
  }
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
@@ -32,7 +32,6 @@
import org.forgerock.opendj.ldap.ConditionResult;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
import org.opends.server.api.AbstractMatchingRule.DefaultAssertion;
/**
 * This class defines the set of methods and structures that must be
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/NotImplementedAssertion.java
File was deleted
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -42,7 +42,6 @@
import org.forgerock.opendj.ldap.spi.IndexingOptions;
import org.forgerock.util.Utils;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType;
import org.opends.server.admin.std.server.LocalDBIndexCfg;
import org.opends.server.api.ExtensibleIndexer;
@@ -53,7 +52,10 @@
import org.opends.server.types.*;
import org.opends.server.util.StaticUtils;
import com.sleepycat.je.*;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import com.sleepycat.je.Transaction;
import static org.opends.messages.JebMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -76,7 +78,17 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /*
   * FIXME Matthew Swift: Once the matching rules have been migrated we should
   * revisit this class. IMO the core indexes (equality, etc) should all be
   * treated in the same way as extensible indexes. In other words, there should
   * be one table mapping index ID to index and one IndexQueryFactory. Matching
   * rules should then be able to select which indexes they need to use when
   * evaluating searches, and all index queries should be processed using the
   * IndexQueryFactory implementation. Moreover, all of the evaluateXXX methods
   * should go (the Matcher class in the SDK could implement the logic, I hope).
   * That's the theory at least...
   */
  /**
   * A database key for the presence index.
@@ -88,52 +100,23 @@
   * The entryContainer in which this attribute index resides.
   */
  private EntryContainer entryContainer;
  private Environment env;
  private State state;
  /**
   * The attribute index configuration.
   */
  private LocalDBIndexCfg indexConfig;
  /**
   * The index database for attribute equality.
   */
  Index equalityIndex = null;
  /**
   * The index database for attribute presence.
   */
  Index presenceIndex = null;
  /**
   * The index database for attribute substrings.
   */
  Index substringIndex = null;
  /**
   * The index database for attribute ordering.
   */
  Index orderingIndex = null;
  /**
   * The index database for attribute approximate.
   */
  Index approximateIndex = null;
  /** The mapping from names to indexes. */
  private Map<String, Index> nameToIndexes;
  private IndexQueryFactory<IndexQuery> indexQueryFactory;
  private final Map<String, Index> nameToIndexes;
  private final IndexQueryFactory<IndexQuery> indexQueryFactory;
  /**
   * The ExtensibleMatchingRuleIndex instance for ExtensibleMatchingRule
   * indexes.
   */
  private  ExtensibleMatchingRuleIndex extensibleIndexes = null;
  private State state;
  private ExtensibleMatchingRuleIndex extensibleIndexes;
  private int cursorEntryLimit = 100000;
  /**
@@ -158,40 +141,41 @@
    AttributeType attrType = indexConfig.getAttribute();
    String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
    final int indexEntryLimit = indexConfig.getIndexEntryLimit();
    final JEIndexConfig config = new JEIndexConfig(indexConfig.getSubstringLength());
    if (indexConfig.getIndexType().contains(IndexType.EQUALITY))
    {
      this.equalityIndex = buildExtIndex(
          name, attrType, attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
      Index equalityIndex = buildExtIndex(name, attrType, indexEntryLimit,
          attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
      nameToIndexes.put(IndexType.EQUALITY.toString(), equalityIndex);
    }
    if (indexConfig.getIndexType().contains(IndexType.PRESENCE))
    {
      this.presenceIndex = newIndex(name + ".presence",
          new PresenceIndexer(attrType), indexConfig.getIndexEntryLimit());
      Index presenceIndex = newIndex(name + "." + IndexType.PRESENCE.toString(),
          indexEntryLimit, new PresenceIndexer(attrType));
      nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
    }
    if (indexConfig.getIndexType().contains(IndexType.SUBSTRING))
    {
      this.substringIndex = buildExtIndex(
          name, attrType, attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType, config));
      Index substringIndex = buildExtIndex(name, attrType, indexEntryLimit,
          attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType, config));
      nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
    }
    if (indexConfig.getIndexType().contains(IndexType.ORDERING))
    {
      this.orderingIndex = buildExtIndex(
          name, attrType, attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
      Index orderingIndex = buildExtIndex(name, attrType, indexEntryLimit,
          attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
      nameToIndexes.put(IndexType.ORDERING.toString(), orderingIndex);
    }
    if (indexConfig.getIndexType().contains(IndexType.APPROXIMATE))
    {
      this.approximateIndex = buildExtIndex(
          name, attrType, attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
      Index approximateIndex = buildExtIndex(name, attrType, indexEntryLimit,
          attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
      nameToIndexes.put(IndexType.APPROXIMATE.toString(), approximateIndex);
    }
@@ -227,7 +211,7 @@
          {
            //There is no index available for this index id. Create a new index.
            String indexName = entryContainer.getDatabasePrefix() + "_" + indexID;
            Index extIndex = newExtensibleIndex(indexName, attrType, indexer);
            Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
            extensibleIndexes.addIndex(extIndex, indexID);
          }
          extensibleIndexes.addRule(indexID, rule);
@@ -239,15 +223,14 @@
    }
  }
  private Index newIndex(String indexName, Indexer indexer,
      int indexEntryLimit)
  private Index newIndex(String indexName, int indexEntryLimit, Indexer indexer)
  {
    return new Index(indexName, indexer, state, indexEntryLimit,
        cursorEntryLimit, false, env, entryContainer);
  }
  private Index buildExtIndex(String name, AttributeType attrType,
      MatchingRule rule, ExtensibleIndexer extIndexer) throws ConfigException
      int indexEntryLimit, MatchingRule rule, ExtensibleIndexer extIndexer) throws ConfigException
  {
    if (rule == null)
    {
@@ -256,14 +239,14 @@
    }
    final String indexName = name + "." + extIndexer.getExtensibleIndexID();
    return newExtensibleIndex(indexName, attrType, extIndexer);
    return newExtensibleIndex(indexName, attrType, indexEntryLimit, extIndexer);
  }
  private Index newExtensibleIndex(String indexName, AttributeType attrType,
      ExtensibleIndexer extIndexer)
      int indexEntryLimit, ExtensibleIndexer extIndexer)
  {
    return newIndex(indexName, new JEExtensibleIndexer(attrType, extIndexer),
        indexConfig.getIndexEntryLimit());
    JEExtensibleIndexer indexer = new JEExtensibleIndexer(attrType, extIndexer);
    return newIndex(indexName, indexEntryLimit, indexer);
  }
  /**
@@ -274,12 +257,10 @@
   */
  public void open() throws DatabaseException
  {
    open(equalityIndex);
    open(presenceIndex);
    open(substringIndex);
    open(orderingIndex);
    open(approximateIndex);
    for (Index index : nameToIndexes.values())
    {
      index.open();
    }
    if(extensibleIndexes!=null)
    {
      for(Index extensibleIndex:extensibleIndexes.getIndexes())
@@ -291,14 +272,6 @@
    indexConfig.addChangeListener(this);
  }
  private void open(Index index)
  {
    if (index != null)
    {
      index.open();
    }
  }
  /**
   * Close the attribute index.
   *
@@ -307,9 +280,7 @@
   */
  public void close() throws DatabaseException
  {
    Utils.closeSilently(equalityIndex, presenceIndex, substringIndex,
        orderingIndex, approximateIndex);
    Utils.closeSilently(nameToIndexes.values());
    if(extensibleIndexes!=null)
    {
      Utils.closeSilently(extensibleIndexes.getIndexes());
@@ -354,11 +325,13 @@
  {
    boolean success = true;
    success = addEntry(equalityIndex, buffer, entryID, entry, success);
    success = addEntry(presenceIndex, buffer, entryID, entry, success);
    success = addEntry(substringIndex, buffer, entryID, entry, success);
    success = addEntry(orderingIndex, buffer, entryID, entry, success);
    success = addEntry(approximateIndex, buffer, entryID, entry, success);
    for (Index index : nameToIndexes.values())
    {
      if (!index.addEntry(buffer, entryID, entry))
      {
        success = false;
      }
    }
    if(extensibleIndexes!=null)
    {
@@ -374,16 +347,6 @@
    return success;
  }
  private boolean addEntry(Index index, IndexBuffer buffer, EntryID entryID,
      Entry entry, boolean success) throws DirectoryException, DatabaseException
  {
    if (index != null && !index.addEntry(buffer, entryID, entry))
    {
      return false;
    }
    return success;
  }
  /**
   * Update the attribute index for a new entry.
   *
@@ -400,11 +363,13 @@
  {
    boolean success = true;
    success = addEntry(equalityIndex, txn, entryID, entry, success);
    success = addEntry(presenceIndex, txn, entryID, entry, success);
    success = addEntry(substringIndex, txn, entryID, entry, success);
    success = addEntry(orderingIndex, txn, entryID, entry, success);
    success = addEntry(approximateIndex, txn, entryID, entry, success);
    for (Index index : nameToIndexes.values())
    {
      if (!index.addEntry(txn, entryID, entry))
      {
        success = false;
      }
    }
    if(extensibleIndexes!=null)
    {
@@ -420,17 +385,6 @@
    return success;
  }
  private boolean addEntry(Index index, Transaction txn, EntryID entryID,
      Entry entry, boolean success) throws DirectoryException, DatabaseException
  {
    if (index != null && !index.addEntry(txn, entryID, entry))
    {
      return false;
    }
    return success;
  }
  /**
   * Update the attribute index for a deleted entry.
   *
@@ -444,11 +398,10 @@
                          Entry entry)
       throws DatabaseException, DirectoryException
  {
    removeEntry(equalityIndex, buffer, entryID, entry);
    removeEntry(presenceIndex, buffer, entryID, entry);
    removeEntry(substringIndex, buffer, entryID, entry);
    removeEntry(orderingIndex, buffer, entryID, entry);
    removeEntry(approximateIndex, buffer, entryID, entry);
    for (Index index : nameToIndexes.values())
    {
      index.removeEntry(buffer, entryID, entry);
    }
    if(extensibleIndexes!=null)
    {
@@ -459,15 +412,6 @@
    }
  }
  private void removeEntry(Index index, IndexBuffer buffer, EntryID entryID,
      Entry entry) throws DirectoryException, DatabaseException
  {
    if (index != null)
    {
      index.removeEntry(buffer, entryID, entry);
    }
  }
  /**
   * Update the attribute index for a deleted entry.
   *
@@ -480,11 +424,10 @@
  public void removeEntry(Transaction txn, EntryID entryID, Entry entry)
       throws DatabaseException, DirectoryException
  {
    removeEntry(equalityIndex, txn, entryID, entry);
    removeEntry(presenceIndex, txn, entryID, entry);
    removeEntry(substringIndex, txn, entryID, entry);
    removeEntry(orderingIndex, txn, entryID, entry);
    removeEntry(approximateIndex, txn, entryID, entry);
    for (Index index : nameToIndexes.values())
    {
      index.removeEntry(txn, entryID, entry);
    }
    if(extensibleIndexes!=null)
    {
@@ -495,15 +438,6 @@
    }
  }
  private void removeEntry(Index index, Transaction txn, EntryID entryID,
      Entry entry) throws DirectoryException, DatabaseException
  {
    if (index != null)
    {
      index.removeEntry(txn, entryID, entry);
    }
  }
  /**
   * Update the index to reflect a sequence of modifications in a Modify
   * operation.
@@ -523,11 +457,10 @@
                          List<Modification> mods)
       throws DatabaseException
  {
    modifyEntry(equalityIndex, txn, entryID, oldEntry, newEntry, mods);
    modifyEntry(presenceIndex, txn, entryID, oldEntry, newEntry, mods);
    modifyEntry(substringIndex, txn, entryID, oldEntry, newEntry, mods);
    modifyEntry(orderingIndex, txn, entryID, oldEntry, newEntry, mods);
    modifyEntry(approximateIndex, txn, entryID, oldEntry, newEntry, mods);
    for (Index index : nameToIndexes.values())
    {
      index.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
    }
    if(extensibleIndexes!=null)
    {
@@ -538,16 +471,6 @@
    }
  }
  private void modifyEntry(Index index, Transaction txn, EntryID entryID,
      Entry oldEntry, Entry newEntry, List<Modification> mods)
      throws DatabaseException
  {
    if (index != null)
    {
      index.modifyEntry(txn, entryID, oldEntry, newEntry, mods);
    }
  }
  /**
   * Update the index to reflect a sequence of modifications in a Modify
   * operation.
@@ -567,11 +490,10 @@
                          List<Modification> mods)
       throws DatabaseException
  {
    modifyEntry(equalityIndex, buffer, entryID, oldEntry, newEntry, mods);
    modifyEntry(presenceIndex, buffer, entryID, oldEntry, newEntry, mods);
    modifyEntry(substringIndex, buffer, entryID, oldEntry, newEntry, mods);
    modifyEntry(orderingIndex, buffer, entryID, oldEntry, newEntry, mods);
    modifyEntry(approximateIndex, buffer, entryID, oldEntry, newEntry, mods);
    for (Index index : nameToIndexes.values())
    {
      index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
    }
    if(extensibleIndexes!=null)
    {
@@ -582,16 +504,6 @@
    }
  }
  private void modifyEntry(Index index, IndexBuffer buffer, EntryID entryID,
      Entry oldEntry, Entry newEntry, List<Modification> mods)
      throws DatabaseException
  {
    if (index != null)
    {
      index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
    }
  }
  /**
   * Makes a byte array representing a substring index key for
   * one substring of a value.
@@ -700,9 +612,8 @@
   * @return The candidate entry IDs that might contain the filter
   *         assertion value.
   */
  public EntryIDSet evaluateEqualityFilter(SearchFilter equalityFilter,
                                           StringBuilder debugBuffer,
                                           DatabaseEnvironmentMonitor monitor)
  public EntryIDSet evaluateEqualityFilter(SearchFilter equalityFilter, StringBuilder debugBuffer,
      DatabaseEnvironmentMonitor monitor)
  {
    try {
      final MatchingRule matchRule = equalityFilter.getAttributeType().getEqualityMatchingRule();
@@ -729,9 +640,8 @@
   * @return The candidate entry IDs that might contain one or more
   *         values of the attribute type in the filter.
   */
  public EntryIDSet evaluatePresenceFilter(SearchFilter filter,
                                           StringBuilder debugBuffer,
                                           DatabaseEnvironmentMonitor monitor)
  public EntryIDSet evaluatePresenceFilter(SearchFilter filter, StringBuilder debugBuffer,
      DatabaseEnvironmentMonitor monitor)
  {
    final IndexQuery indexQuery = indexQueryFactory.createMatchAllQuery();
    return evaluateIndexQuery(indexQuery, "presence", filter, debugBuffer, monitor);
@@ -749,8 +659,7 @@
   * @return The candidate entry IDs that might contain a value
   *         greater than or equal to the filter assertion value.
   */
  public EntryIDSet evaluateGreaterOrEqualFilter(
      SearchFilter filter, StringBuilder debugBuffer,
  public EntryIDSet evaluateGreaterOrEqualFilter(SearchFilter filter, StringBuilder debugBuffer,
      DatabaseEnvironmentMonitor monitor)
  {
    return evaluateOrderingFilter(filter, true, debugBuffer, monitor);
@@ -901,10 +810,7 @@
      {
        return 1;
      }
      else
      {
        return -1;
      }
      return -1;
    }
  }
@@ -954,10 +860,7 @@
      {
        return 1;
      }
      else
      {
        return -1;
      }
      return -1;
    }
  }
@@ -995,29 +898,9 @@
   * @throws DatabaseException If a database error occurs.
   */
  public void closeCursors() throws DatabaseException {
    if (equalityIndex != null)
    for (Index index : nameToIndexes.values())
    {
      equalityIndex.closeCursor();
    }
    if (presenceIndex != null)
    {
      presenceIndex.closeCursor();
    }
    if (substringIndex != null)
    {
      substringIndex.closeCursor();
    }
    if (orderingIndex != null)
    {
      orderingIndex.closeCursor();
    }
    if (approximateIndex != null)
    {
      approximateIndex.closeCursor();
      index.closeCursor();
    }
    if(extensibleIndexes!=null)
@@ -1039,38 +922,16 @@
  {
    long entryLimitExceededCount = 0;
    if (equalityIndex != null)
    for (Index index : nameToIndexes.values())
    {
      entryLimitExceededCount += equalityIndex.getEntryLimitExceededCount();
      entryLimitExceededCount += index.getEntryLimitExceededCount();
    }
    if (presenceIndex != null)
    {
      entryLimitExceededCount += presenceIndex.getEntryLimitExceededCount();
    }
    if (substringIndex != null)
    {
      entryLimitExceededCount += substringIndex.getEntryLimitExceededCount();
    }
    if (orderingIndex != null)
    {
      entryLimitExceededCount += orderingIndex.getEntryLimitExceededCount();
    }
    if (approximateIndex != null)
    {
      entryLimitExceededCount +=
          approximateIndex.getEntryLimitExceededCount();
    }
     if(extensibleIndexes!=null)
    if (extensibleIndexes != null)
    {
      for(Index extensibleIndex:extensibleIndexes.getIndexes())
      {
        entryLimitExceededCount +=
                extensibleIndex.getEntryLimitExceededCount();
        entryLimitExceededCount += extensibleIndex.getEntryLimitExceededCount();
      }
    }
    return entryLimitExceededCount;
@@ -1082,11 +943,7 @@
   */
  public void listDatabases(List<DatabaseContainer> dbList)
  {
    addIfNotNull(dbList, equalityIndex);
    addIfNotNull(dbList, presenceIndex);
    addIfNotNull(dbList, substringIndex);
    addIfNotNull(dbList, orderingIndex);
    addIfNotNull(dbList, approximateIndex);
    dbList.addAll(nameToIndexes.values());
    if(extensibleIndexes!=null)
    {
@@ -1094,14 +951,6 @@
    }
  }
  private void addIfNotNull(Collection<? super Index> dbList, Index index)
  {
    if (index != null)
    {
      dbList.add(index);
    }
  }
  /**
   * Get a string representation of this object.
   * @return return A string representation of this object.
@@ -1115,42 +964,39 @@
  /** {@inheritDoc} */
  @Override
  public synchronized boolean isConfigurationChangeAcceptable(
      LocalDBIndexCfg cfg,
      List<LocalizableMessage> unacceptableReasons)
      LocalDBIndexCfg cfg, List<LocalizableMessage> unacceptableReasons)
  {
    AttributeType attrType = cfg.getAttribute();
    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EQUALITY)
        && equalityIndex == null
    if (cfg.getIndexType().contains(IndexType.EQUALITY)
        && nameToIndexes.get(IndexType.EQUALITY.toString()) == null
        && attrType.getEqualityMatchingRule() == null)
    {
      unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "equality"));
      return false;
    }
    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.SUBSTRING)
        && substringIndex == null
    if (cfg.getIndexType().contains(IndexType.SUBSTRING)
        && nameToIndexes.get(IndexType.SUBSTRING.toString()) == null
        && attrType.getSubstringMatchingRule() == null)
    {
      unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "substring"));
      return false;
    }
    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.ORDERING)
        && orderingIndex == null
    if (cfg.getIndexType().contains(IndexType.ORDERING)
        && nameToIndexes.get(IndexType.ORDERING.toString()) == null
        && attrType.getOrderingMatchingRule() == null)
    {
      unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "ordering"));
      return false;
    }
    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.APPROXIMATE)
        && approximateIndex == null
    if (cfg.getIndexType().contains(IndexType.APPROXIMATE)
        && nameToIndexes.get(IndexType.APPROXIMATE.toString()) == null
        && attrType.getApproximateMatchingRule() == null)
    {
      unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "approximate"));
      return false;
    }
    if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
    if (cfg.getIndexType().contains(IndexType.EXTENSIBLE))
    {
      Set<String> newRules = cfg.getIndexExtensibleMatchingRule();
      if (newRules == null || newRules.isEmpty())
@@ -1178,56 +1024,23 @@
      final int indexEntryLimit = cfg.getIndexEntryLimit();
      final JEIndexConfig config = new JEIndexConfig(cfg.getSubstringLength());
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EQUALITY))
      {
        if (equalityIndex == null)
        {
          equalityIndex = openNewIndex(name, attrType,
              new EqualityIndexer(attrType), adminActionRequired, messages);
          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString(), equalityIndex);
        }
        else
        {
          // already exists. Just update index entry limit.
          if(this.equalityIndex.setIndexEntryLimit(indexEntryLimit))
          {
            adminActionRequired.set(true);
            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(equalityIndex.getName()));
            this.equalityIndex.setIndexEntryLimit(indexEntryLimit);
          }
        }
      }
      else
      {
        if (equalityIndex != null)
        {
          entryContainer.exclusiveLock.lock();
          try
          {
            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString());
            entryContainer.deleteDatabase(equalityIndex);
            equalityIndex = null;
          }
          finally
          {
            entryContainer.exclusiveLock.unlock();
          }
        }
      }
      applyChangeToIndex(cfg, attrType, name, IndexType.EQUALITY,
          new EqualityIndexer(attrType), adminActionRequired, messages);
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.PRESENCE))
      Index presenceIndex = nameToIndexes.get(IndexType.PRESENCE.toString());
      if (cfg.getIndexType().contains(IndexType.PRESENCE))
      {
        if(presenceIndex == null)
        {
          Indexer presenceIndexer = new PresenceIndexer(attrType);
          presenceIndex = newIndex(name + ".presence", presenceIndexer, indexEntryLimit);
          presenceIndex = newIndex(name + ".presence", indexEntryLimit, presenceIndexer);
          openIndex(presenceIndex, adminActionRequired, messages);
          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString(), presenceIndex);
          nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
        }
        else
        {
          // already exists. Just update index entry limit.
          if(this.presenceIndex.setIndexEntryLimit(indexEntryLimit))
          if(presenceIndex.setIndexEntryLimit(indexEntryLimit))
          {
            adminActionRequired.set(true);
            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(presenceIndex.getName()));
@@ -1236,37 +1049,25 @@
      }
      else
      {
        if (presenceIndex != null)
        {
          entryContainer.exclusiveLock.lock();
          try
          {
            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString());
            entryContainer.deleteDatabase(presenceIndex);
            presenceIndex = null;
          }
          finally
          {
            entryContainer.exclusiveLock.unlock();
          }
        }
        removeIndex(presenceIndex, IndexType.PRESENCE);
      }
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.SUBSTRING))
      Index substringIndex = nameToIndexes.get(IndexType.SUBSTRING.toString());
      if (cfg.getIndexType().contains(IndexType.SUBSTRING))
      {
        SubstringIndexer indexer = new SubstringIndexer(attrType, config);
        Indexer extIndexer = new JEExtensibleIndexer(attrType, indexer);
        if(substringIndex == null)
        {
          Index index = newIndex(name + "." + indexer.getExtensibleIndexID(),
              extIndexer, indexEntryLimit);
              indexEntryLimit, extIndexer);
          substringIndex = openIndex(index, adminActionRequired, messages);
          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString(), substringIndex);
          nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
        }
        else
        {
          // already exists. Just update index entry limit.
          if(this.substringIndex.setIndexEntryLimit(indexEntryLimit))
          if(substringIndex.setIndexEntryLimit(indexEntryLimit))
          {
            adminActionRequired.set(true);
            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(substringIndex.getName()));
@@ -1274,101 +1075,21 @@
          if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
          {
            this.substringIndex.setIndexer(extIndexer);
            substringIndex.setIndexer(extIndexer);
          }
        }
      }
      else
      {
        if (substringIndex != null)
        {
          entryContainer.exclusiveLock.lock();
          try
          {
            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString());
            entryContainer.deleteDatabase(substringIndex);
            substringIndex = null;
          }
          finally
          {
            entryContainer.exclusiveLock.unlock();
          }
        }
        removeIndex(substringIndex, IndexType.SUBSTRING);
      }
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.ORDERING))
      {
        if(orderingIndex == null)
        {
          orderingIndex = openNewIndex(name, attrType,
              new OrderingIndexer(attrType), adminActionRequired, messages);
          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.ORDERING.toString(), orderingIndex);
        }
        else
        {
          // already exists. Just update index entry limit.
          if(this.orderingIndex.setIndexEntryLimit(indexEntryLimit))
          {
            adminActionRequired.set(true);
            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(orderingIndex.getName()));
          }
        }
      }
      else
      {
        if (orderingIndex != null)
        {
          entryContainer.exclusiveLock.lock();
          try
          {
            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.ORDERING.toString());
            entryContainer.deleteDatabase(orderingIndex);
            orderingIndex = null;
          }
          finally
          {
            entryContainer.exclusiveLock.unlock();
          }
        }
      }
      applyChangeToIndex(cfg, attrType, name, IndexType.ORDERING,
          new OrderingIndexer(attrType), adminActionRequired, messages);
      applyChangeToIndex(cfg, attrType, name, IndexType.APPROXIMATE,
          new ApproximateIndexer(attrType), adminActionRequired, messages);
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.APPROXIMATE))
      {
        if(approximateIndex == null)
        {
          approximateIndex = openNewIndex(name, attrType,
              new ApproximateIndexer(attrType), adminActionRequired, messages);
          nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.APPROXIMATE.toString(), approximateIndex);
        }
        else
        {
          // already exists. Just update index entry limit.
          if(this.approximateIndex.setIndexEntryLimit(indexEntryLimit))
          {
            adminActionRequired.set(true);
            messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(approximateIndex.getName()));
          }
        }
      }
      else
      {
        if (approximateIndex != null)
        {
          entryContainer.exclusiveLock.lock();
          try
          {
            nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.APPROXIMATE.toString());
            entryContainer.deleteDatabase(approximateIndex);
            approximateIndex = null;
          }
          finally
          {
            entryContainer.exclusiveLock.unlock();
          }
        }
      }
      if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
      if (cfg.getIndexType().contains(IndexType.EXTENSIBLE))
      {
        Set<String> extensibleRules = cfg.getIndexExtensibleMatchingRule();
        Set<ExtensibleMatchingRule> validRules = new HashSet<ExtensibleMatchingRule>();
@@ -1392,7 +1113,7 @@
            if(!extensibleIndexes.isIndexPresent(indexID))
            {
              String indexName =  entryContainer.getDatabasePrefix() + "_" + indexID;
              Index extIndex = newExtensibleIndex(indexName, attrType, indexer);
              Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
              extensibleIndexes.addIndex(extIndex,indexID);
              openIndex(extIndex, adminActionRequired, messages);
            }
@@ -1427,14 +1148,13 @@
          {
            for(ExtensibleMatchingRule rule:deletedRules)
            {
              Set<ExtensibleMatchingRule> rules =
                      new HashSet<ExtensibleMatchingRule>();
              Set<ExtensibleMatchingRule> rules = new HashSet<ExtensibleMatchingRule>();
              List<String> ids = new ArrayList<String>();
              for (ExtensibleIndexer indexer : rule.getIndexers())
              {
                String id = attrType.getNameOrOID()  + "." + indexer.getIndexID();
                rules.addAll(extensibleIndexes.getRules(id));
                ids.add(id);
                rules.addAll(extensibleIndexes.getRules(id));
              }
              if(rules.isEmpty())
              {
@@ -1500,12 +1220,60 @@
    }
  }
  private Index openNewIndex(String name, AttributeType attrType,
      ExtensibleIndexer indexer, AtomicBoolean adminActionRequired,
      ArrayList<LocalizableMessage> messages)
  private void applyChangeToIndex(LocalDBIndexCfg cfg, AttributeType attrType,
      String name, IndexType indexType, ExtensibleIndexer indexer,
      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
  {
    String indexName = name + "." + indexer.getExtensibleIndexID();
    Index index = newExtensibleIndex(indexName, attrType, indexer);
    final int indexEntryLimit = cfg.getIndexEntryLimit();
    Index index = nameToIndexes.get(indexType.toString());
    if (cfg.getIndexType().contains(indexType))
    {
      if (index == null)
      {
        index = openNewIndex(name, attrType, indexEntryLimit,
            indexer, adminActionRequired, messages);
        nameToIndexes.put(indexType.toString(), index);
      }
      else
      {
        // already exists. Just update index entry limit.
        if(index.setIndexEntryLimit(indexEntryLimit))
        {
          adminActionRequired.set(true);
          messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
        }
      }
    }
    else
    {
      removeIndex(index, indexType);
    }
  }
  private void removeIndex(Index index, IndexType indexType)
  {
    if (index != null)
    {
      entryContainer.exclusiveLock.lock();
      try
      {
        nameToIndexes.remove(indexType.toString());
        entryContainer.deleteDatabase(index);
      }
      finally
      {
        entryContainer.exclusiveLock.unlock();
      }
    }
  }
  private Index openNewIndex(String name, AttributeType attrType,
      int indexEntryLimit, ExtensibleIndexer indexer,
      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
  {
    final String indexName = name + "." + indexer.getExtensibleIndexID();
    Index index = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
    return openIndex(index, adminActionRequired, messages);
  }
@@ -1532,11 +1300,10 @@
  public synchronized void setTrusted(Transaction txn, boolean trusted)
      throws DatabaseException
  {
    setTrusted(equalityIndex, txn, trusted);
    setTrusted(presenceIndex, txn, trusted);
    setTrusted(substringIndex, txn, trusted);
    setTrusted(orderingIndex, txn, trusted);
    setTrusted(approximateIndex, txn, trusted);
    for (Index index : nameToIndexes.values())
    {
      index.setTrusted(txn, trusted);
    }
    if(extensibleIndexes!=null)
    {
@@ -1547,34 +1314,25 @@
    }
  }
  private void setTrusted(Index index, Transaction txn, boolean trusted)
  {
    if (index != null)
    {
      index.setTrusted(txn, trusted);
    }
  }
  /**
   * Return true iff this index is trusted.
   * @return the trusted state of this index
   */
  public boolean isTrusted()
  {
    if ((equalityIndex != null && !equalityIndex.isTrusted())
        || (presenceIndex != null && !presenceIndex.isTrusted())
        || (substringIndex != null && !substringIndex.isTrusted())
        || (orderingIndex != null && !orderingIndex.isTrusted())
        || (approximateIndex != null && !approximateIndex.isTrusted()))
    for (Index index : nameToIndexes.values())
    {
      return false;
      if (!index.isTrusted())
      {
        return false;
      }
    }
    if(extensibleIndexes!=null)
    {
      for(Index extensibleIndex:extensibleIndexes.getIndexes())
      {
        if(extensibleIndex !=null && !extensibleIndex.isTrusted())
        if (!extensibleIndex.isTrusted())
        {
          return false;
        }
@@ -1591,11 +1349,10 @@
   */
  public synchronized void setRebuildStatus(boolean rebuildRunning)
  {
    setRebuildStatus(rebuildRunning, equalityIndex);
    setRebuildStatus(rebuildRunning, presenceIndex);
    setRebuildStatus(rebuildRunning, substringIndex);
    setRebuildStatus(rebuildRunning, orderingIndex);
    setRebuildStatus(rebuildRunning, approximateIndex);
    for (Index index : nameToIndexes.values())
    {
      index.setRebuildStatus(rebuildRunning);
    }
    if(extensibleIndexes!=null)
    {
@@ -1606,14 +1363,6 @@
    }
  }
  private void setRebuildStatus(boolean rebuildRunning, Index index)
  {
    if (index != null)
    {
      index.setRebuildStatus(rebuildRunning);
    }
  }
  /**
   * Get the JE database name prefix for indexes in this attribute index.
   *
@@ -1632,7 +1381,7 @@
   * @return The equality index.
   */
  public Index getEqualityIndex() {
    return  equalityIndex;
    return nameToIndexes.get(IndexType.EQUALITY.toString());
  }
  /**
@@ -1641,7 +1390,7 @@
   * @return The approximate index.
   */
  public Index getApproximateIndex() {
    return approximateIndex;
    return nameToIndexes.get(IndexType.APPROXIMATE.toString());
  }
  /**
@@ -1650,7 +1399,7 @@
   * @return  The ordering index.
   */
  public Index getOrderingIndex() {
    return orderingIndex;
    return nameToIndexes.get(IndexType.ORDERING.toString());
  }
  /**
@@ -1659,7 +1408,7 @@
   * @return The substring index.
   */
  public Index getSubstringIndex() {
    return substringIndex;
    return nameToIndexes.get(IndexType.SUBSTRING.toString());
  }
  /**
@@ -1668,7 +1417,7 @@
   * @return The presence index.
   */
  public Index getPresenceIndex() {
    return presenceIndex;
    return nameToIndexes.get(IndexType.PRESENCE.toString());
  }
  /**
@@ -1678,11 +1427,11 @@
   */
  public Map<String,Collection<Index>> getExtensibleIndexes()
  {
    if(extensibleIndexes == null)
    if (extensibleIndexes != null)
    {
      return Collections.emptyMap();
      return extensibleIndexes.getIndexMap();
    }
    return extensibleIndexes.getIndexMap();
    return Collections.emptyMap();
  }
@@ -1694,19 +1443,11 @@
   */
  public Collection<Index> getAllIndexes() {
    LinkedHashSet<Index> indexes = new LinkedHashSet<Index>();
    addIfNotNull(indexes, equalityIndex);
    addIfNotNull(indexes, presenceIndex);
    addIfNotNull(indexes, substringIndex);
    addIfNotNull(indexes, orderingIndex);
    addIfNotNull(indexes, approximateIndex);
    indexes.addAll(nameToIndexes.values());
    if(extensibleIndexes!=null)
    {
      for(Index extensibleIndex:extensibleIndexes.getIndexes())
      {
        indexes.add(extensibleIndex);
      }
      indexes.addAll(extensibleIndexes.getIndexes());
    }
    return indexes;
  }
@@ -1715,7 +1456,7 @@
  /**
   * Retrieve the entry IDs that might match an extensible filter.
   *
   * @param extensibleFilter The extensible filter.
   * @param filter The extensible filter.
   * @param debugBuffer If not null, a diagnostic string will be written
   *                     which will help determine how the indexes contributed
   *                     to this search.
@@ -1724,12 +1465,12 @@
   * @return The candidate entry IDs that might contain the filter
   *         assertion value.
   */
  public EntryIDSet evaluateExtensibleFilter(SearchFilter extensibleFilter,
  public EntryIDSet evaluateExtensibleFilter(SearchFilter filter,
                                             StringBuilder debugBuffer,
                                             DatabaseEnvironmentMonitor monitor)
  {
    //Get the Matching Rule OID of the filter.
    String matchRuleOID  = extensibleFilter.getMatchingRuleID();
    String matchRuleOID  = filter.getMatchingRuleID();
    /**
     * Use the default equality index in two conditions:
     * 1. There is no matching rule provided
@@ -1741,7 +1482,7 @@
        || matchRuleOID.equalsIgnoreCase(eqRule.getNameOrOID()))
    {
      //No matching rule is defined; use the default equality matching rule.
      return evaluateEqualityFilter(extensibleFilter, debugBuffer, monitor);
      return evaluateEqualityFilter(filter, debugBuffer, monitor);
    }
    ExtensibleMatchingRule rule = DirectoryServer.getExtensibleMatchingRule(matchRuleOID);
@@ -1751,7 +1492,7 @@
      // There is no index on this matching rule.
      if (monitor.isFilterUseEnabled())
      {
        monitor.updateStats(extensibleFilter, INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(
        monitor.updateStats(filter, INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(
            matchRuleOID, indexConfig.getAttribute().getNameOrOID()));
      }
      return IndexQuery.createNullIndexQuery().evaluate(null);
@@ -1765,28 +1506,28 @@
        for (ExtensibleIndexer indexer : rule.getIndexers())
        {
          debugBuffer.append(" ")
                     .append(extensibleFilter.getAttributeType().getNameOrOID())
                     .append(filter.getAttributeType().getNameOrOID())
                     .append(".")
                     .append(indexer.getIndexID());
        }
        debugBuffer.append("]");
      }
      ByteString assertionValue = extensibleFilter.getAssertionValue();
      IndexQuery expression = rule.createIndexQuery(assertionValue, factory);
      ByteString assertionValue = filter.getAssertionValue();
      IndexQuery indexQuery = rule.createIndexQuery(assertionValue, factory);
      LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
      EntryIDSet idSet = expression.evaluate(debugMessage);
      EntryIDSet results = indexQuery.evaluate(debugMessage);
      if (monitor.isFilterUseEnabled())
      {
        if (idSet.isDefined())
        if (results.isDefined())
        {
          monitor.updateStats(extensibleFilter, idSet.size());
          monitor.updateStats(filter, results.size());
        }
        else
        {
          monitor.updateStats(extensibleFilter, debugMessage.toMessage());
          monitor.updateStats(filter, debugMessage.toMessage());
        }
      }
      return idSet;
      return results;
    }
    catch (DecodeException e)
    {
@@ -2031,7 +1772,6 @@
    /** The length of the substring index. */
    private int substringLength;
    /**
     * Creates a new JEIndexConfig instance.
     * @param substringLength The length of the substring.
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -3271,52 +3271,22 @@
  /**
   * Removes a attribute index from disk.
   *
   * @param index The attribute index to remove.
   * @param attributeIndex The attribute index to remove.
   * @throws DatabaseException If an JE database error occurs while attempting
   * to delete the index.
   */
  public void deleteAttributeIndex(AttributeIndex index)
  public void deleteAttributeIndex(AttributeIndex attributeIndex)
  throws DatabaseException
  {
    index.close();
    attributeIndex.close();
    Transaction txn = env.getConfig().getTransactional()
      ? beginTransaction() : null;
    try
    {
      if(index.equalityIndex != null)
      for (Index index : attributeIndex.getAllIndexes())
      {
        env.removeDatabase(txn, index.equalityIndex.getName());
        state.removeIndexTrustState(txn, index.equalityIndex);
      }
      if(index.presenceIndex != null)
      {
        env.removeDatabase(txn, index.presenceIndex.getName());
        state.removeIndexTrustState(txn, index.presenceIndex);
      }
      if(index.substringIndex != null)
      {
        env.removeDatabase(txn, index.substringIndex.getName());
        state.removeIndexTrustState(txn, index.substringIndex);
      }
      if(index.orderingIndex != null)
      {
        env.removeDatabase(txn, index.orderingIndex.getName());
        state.removeIndexTrustState(txn, index.orderingIndex);
      }
      if(index.approximateIndex != null)
      {
        env.removeDatabase(txn, index.approximateIndex.getName());
        state.removeIndexTrustState(txn, index.approximateIndex);
      }
      Map <String,Collection<Index>> extensibleIndexes =
        index.getExtensibleIndexes();
      for (String name : extensibleIndexes.keySet())
      {
        for (Index extensibleIndex : extensibleIndexes.get(name))
        {
          env.removeDatabase(txn, extensibleIndex.getName());
          state.removeIndexTrustState(txn, extensibleIndex);
        }
        env.removeDatabase(txn, index.getName());
        state.removeIndexTrustState(txn, index);
      }
      if (txn != null)
      {
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
@@ -24,19 +24,14 @@
 *      Copyright 2009-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2014 ForgeRock AS
 */
package org.opends.server.backends.jeb;
import org.forgerock.i18n.LocalizableMessageBuilder;
import java.util.Collection;
import org.forgerock.i18n.LocalizableMessageBuilder;
import static org.opends.server.backends.jeb.IndexFilter.*;
/**
 * This class represents a JE Backend Query.
 */
@@ -111,10 +106,7 @@
   */
  private static final class NullIndexQuery extends IndexQuery
  {
    /**
     * {@inheritDoc}
     * @param debugMessages
     */
    /** {@inheritDoc} */
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    {
@@ -146,12 +138,7 @@
      this.subIndexQueries = subIndexQueries;
    }
    /**
     * {@inheritDoc}
     * @param debugMessages
     */
    /** {@inheritDoc} */
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    {
@@ -199,12 +186,7 @@
      this.subIndexQueries = subIndexQueries;
    }
    /**
     * {@inheritDoc}
     * @param debugMessages
     */
    /** {@inheritDoc} */
    @Override
    public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
    {
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
@@ -73,8 +73,7 @@
  /** {@inheritDoc} */
  @Override
  public IndexQuery createExactMatchQuery(final String indexID,
      final ByteSequence value)
  public IndexQuery createExactMatchQuery(final String indexID, final ByteSequence value)
  {
    return new IndexQuery()
      {
@@ -98,18 +97,7 @@
          EntryIDSet entrySet = index.readKey(key, null, LockMode.DEFAULT);
          if(debugMessage != null && !entrySet.isDefined())
          {
            if(!index.isTrusted())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
            }
            else if(index.isRebuildRunning())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
            }
            else
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
            }
            updateStatsUndefinedResults(debugMessage, index);
          }
          return entrySet;
        }
@@ -144,18 +132,7 @@
              includeLowerBound, includeUpperBound);
          if(debugMessage != null && !entrySet.isDefined())
          {
            if(!index.isTrusted())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
            }
            else if(index.isRebuildRunning())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
            }
            else
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
            }
            updateStatsUndefinedResults(debugMessage, index);
          }
          return entrySet;
        }
@@ -166,8 +143,7 @@
  /** {@inheritDoc} */
  @Override
  public IndexQuery createIntersectionQuery(
      Collection<IndexQuery> subqueries)
  public IndexQuery createIntersectionQuery(Collection<IndexQuery> subqueries)
  {
    return IndexQuery.createIntersectionIndexQuery(subqueries);
  }
@@ -197,39 +173,43 @@
        @Override
        public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
        {
          Index index = indexMap.get(PRESENCE_INDEX_KEY);
        final String indexID = PRESENCE_INDEX_KEY;
        final Index index = indexMap.get(indexID);
          if (index == null)
          {
            if(debugMessage != null)
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(index.getName(), ""));
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID, ""));
            }
            return new EntryIDSet();
          }
          EntryIDSet entrySet = index.readKey(AttributeIndex.presenceKey, null, LockMode.DEFAULT);
          if (debugMessage != null && !entrySet.isDefined())
          {
            if (!index.isTrusted())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
            }
            else if (index.isRebuildRunning())
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
            }
            else
            {
              debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
            }
            updateStatsUndefinedResults(debugMessage, index);
          }
          return entrySet;
        }
      };
  }
  private static void updateStatsUndefinedResults(LocalizableMessageBuilder debugMessage, Index index)
  {
    if (!index.isTrusted())
    {
      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
    }
    else if (index.isRebuildRunning())
    {
      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
    }
    else
    {
      debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
    }
  }
  /** {@inheritDoc} */
  @Override
  public IndexingOptions getIndexingOptions()
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -47,6 +47,12 @@
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.*;
import org.opends.server.types.Attribute;
import org.opends.server.types.Attributes;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.opends.server.types.RDN;
import org.opends.server.util.Base64;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -795,22 +801,17 @@
          entries.get(0).getAttribute("cn").get(0).getAttributeType();
      AttributeIndex index = ec.getAttributeIndex(attribute);
      Indexer presenceIndexer = new PresenceIndexer(index.getAttributeType());
      assertIndexContainsID(presenceIndexer, entry, index.presenceIndex,
          entryID, FALSE);
      assertIndexContainsID(presenceIndexer, entry, index.getPresenceIndex(), entryID, FALSE);
      Indexer equalityIndexer = newEqualityIndexer(index);
      assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
          entryID, FALSE);
      assertIndexContainsID(equalityIndexer, entry, index.getEqualityIndex(), entryID, FALSE);
      Indexer substringIndexer = newSubstringIndexer(index);
      assertIndexContainsID(substringIndexer, entry, index.substringIndex,
          entryID, FALSE);
      assertIndexContainsID(substringIndexer, entry, index.getSubstringIndex(), entryID, FALSE);
      Indexer orderingIndexer = newOrderingIndexer(index);
      assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
          entryID, FALSE);
      assertIndexContainsID(orderingIndexer, entry, index.getOrderingIndex(), entryID, FALSE);
    }
    finally
    {
@@ -909,22 +910,16 @@
      AttributeIndex index = ec.getAttributeIndex(attribute);
      Indexer orderingIndexer = newOrderingIndexer(index);
      assertIndexContainsID(orderingIndexer, entry, index.orderingIndex,
          entryID, TRUE);
      assertIndexContainsID(orderingIndexer, oldEntry, index.orderingIndex,
          entryID, FALSE);
      assertIndexContainsID(orderingIndexer, entry, index.getOrderingIndex(), entryID, TRUE);
      assertIndexContainsID(orderingIndexer, oldEntry, index.getOrderingIndex(), entryID, FALSE);
      Indexer substringIndexer = newSubstringIndexer(index);
      assertIndexContainsID(substringIndexer, entry, index.substringIndex,
          entryID, TRUE);
      assertIndexContainsID(substringIndexer, oldEntry, index.substringIndex,
          entryID, FALSE);
      assertIndexContainsID(substringIndexer, entry, index.getSubstringIndex(), entryID, TRUE);
      assertIndexContainsID(substringIndexer, oldEntry, index.getSubstringIndex(), entryID, FALSE);
      Indexer equalityIndexer = newEqualityIndexer(index);
      assertIndexContainsID(equalityIndexer, entry, index.equalityIndex,
          entryID, TRUE);
      assertIndexContainsID(equalityIndexer, oldEntry, index.equalityIndex,
          entryID, FALSE);
      assertIndexContainsID(equalityIndexer, entry, index.getEqualityIndex(), entryID, TRUE);
      assertIndexContainsID(equalityIndexer, oldEntry, index.getEqualityIndex(), entryID, FALSE);
    }
    finally
    {
@@ -998,16 +993,15 @@
      // This current entry in the DB shouldn't be in the presence titleIndex.
      addKeys = new HashSet<ByteString>();
      addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
      assertIndexContainsID(addKeys, titleIndex.presenceIndex, entryID, FALSE);
      assertIndexContainsID(addKeys, titleIndex.getPresenceIndex(), entryID, FALSE);
      // This current entry should be in the presence nameIndex.
      addKeys = new HashSet<ByteString>();
      addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
      assertIndexContainsID(addKeys, nameIndex.presenceIndex, entryID, TRUE);
      assertIndexContainsID(addKeys, nameIndex.getPresenceIndex(), entryID, TRUE);
      List<Control> noControls = new ArrayList<Control>(0);
      InternalClientConnection conn = InternalClientConnection
          .getRootConnection();
      InternalClientConnection conn = InternalClientConnection.getRootConnection();
      ModifyOperationBasis modifyOp = new ModifyOperationBasis(conn, InternalClientConnection
          .nextOperationID(), InternalClientConnection.nextMessageID(), noControls, DN
@@ -1043,28 +1037,28 @@
          Attributes.create("employeenumber", "1")));
      presenceIndexer = new PresenceIndexer(titleIndex.getAttributeType());
      assertIndexContainsID(presenceIndexer, entry, titleIndex.presenceIndex, entryID);
      assertIndexContainsID(presenceIndexer, entry, titleIndex.getPresenceIndex(), entryID);
      presenceIndexer = new PresenceIndexer(nameIndex.getAttributeType());
      assertIndexContainsID(presenceIndexer, entry, nameIndex.presenceIndex, entryID);
      assertIndexContainsID(presenceIndexer, entry, nameIndex.getPresenceIndex(), entryID);
      orderingIndexer = newOrderingIndexer(titleIndex);
      assertIndexContainsID(orderingIndexer, entry, titleIndex.orderingIndex, entryID);
      assertIndexContainsID(orderingIndexer, entry, titleIndex.getOrderingIndex(), entryID);
      orderingIndexer = newOrderingIndexer(nameIndex);
      assertIndexContainsID(orderingIndexer, entry, nameIndex.orderingIndex, entryID);
      assertIndexContainsID(orderingIndexer, entry, nameIndex.getOrderingIndex(), entryID);
      equalityIndexer = newEqualityIndexer(titleIndex);
      assertIndexContainsID(equalityIndexer, entry, titleIndex.equalityIndex, entryID);
      assertIndexContainsID(equalityIndexer, entry, titleIndex.getEqualityIndex(), entryID);
      equalityIndexer = newEqualityIndexer(nameIndex);
      assertIndexContainsID(equalityIndexer, entry, nameIndex.equalityIndex, entryID);
      assertIndexContainsID(equalityIndexer, entry, nameIndex.getEqualityIndex(), entryID);
      substringIndexer = newSubstringIndexer(titleIndex);
      assertIndexContainsID(substringIndexer, entry, titleIndex.substringIndex, entryID);
      assertIndexContainsID(substringIndexer, entry, titleIndex.getSubstringIndex(), entryID);
      substringIndexer = newSubstringIndexer(nameIndex);
      assertIndexContainsID(substringIndexer, entry, nameIndex.substringIndex, entryID);
      assertIndexContainsID(substringIndexer, entry, nameIndex.getSubstringIndex(), entryID);
    }
    finally
    {
@@ -1210,13 +1204,13 @@
    RootContainer rootContainer = backend.getRootContainer();
    EntryContainer ec = rootContainer.getEntryContainer(DN.valueOf("dc=test,dc=com"));
    AttributeIndex index =
    AttributeIndex attributeIndex =
        ec.getAttributeIndex(DirectoryServer.getAttributeType("givenname"));
    assertNull(index.equalityIndex);
    assertNull(index.presenceIndex);
    assertNull(index.substringIndex);
    assertNull(index.orderingIndex);
    assertNotNull(index.approximateIndex);
    assertNull(attributeIndex.getEqualityIndex());
    assertNull(attributeIndex.getPresenceIndex());
    assertNull(attributeIndex.getSubstringIndex());
    assertNull(attributeIndex.getOrderingIndex());
    assertNotNull(attributeIndex.getApproximateIndex());
    List<DatabaseContainer> databases = new ArrayList<DatabaseContainer>();
    ec.listDatabases(databases);
    boolean eqfound = false;
@@ -1287,11 +1281,11 @@
    assertEquals(resultCode, 0);
    assertNotNull(index.equalityIndex);
    assertNotNull(index.presenceIndex);
    assertNotNull(index.substringIndex);
    assertNotNull(index.orderingIndex);
    assertNull(index.approximateIndex);
    assertNotNull(attributeIndex.getEqualityIndex());
    assertNotNull(attributeIndex.getPresenceIndex());
    assertNotNull(attributeIndex.getSubstringIndex());
    assertNotNull(attributeIndex.getOrderingIndex());
    assertNull(attributeIndex.getApproximateIndex());
    databases = new ArrayList<DatabaseContainer>();
    ec.listDatabases(databases);
    eqfound = false;
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
@@ -345,10 +345,8 @@
    eContainer.sharedLock.lock();
    try
    {
      AttributeType attributeType =
          DirectoryServer.getAttributeType(phoneType);
      Index index =
           eContainer.getAttributeIndex(attributeType).equalityIndex;
      AttributeType attributeType = DirectoryServer.getAttributeType(phoneType);
      Index index = eContainer.getAttributeIndex(attributeType).getEqualityIndex();
      //Add entry with bad JEB format Version
      addID2EntryReturnKey(junkDN, 4, true);
      //Add phone number with various bad id list entryIDs
@@ -634,14 +632,11 @@
      AttributeType attributeType =
          DirectoryServer.getAttributeType(mailType);
      //Get db handles to each index.
      Index eqIndex =
          eContainer.getAttributeIndex(attributeType).equalityIndex;
      Index presIndex =
          eContainer.getAttributeIndex(attributeType).presenceIndex;
      Index subIndex =
          eContainer.getAttributeIndex(attributeType).substringIndex;
      Index ordIndex =
          eContainer.getAttributeIndex(attributeType).orderingIndex;
      AttributeIndex attributeIndex = eContainer.getAttributeIndex(attributeType);
      Index eqIndex = attributeIndex.getEqualityIndex();
      Index presIndex = attributeIndex.getPresenceIndex();
      Index subIndex = attributeIndex.getSubstringIndex();
      Index ordIndex = attributeIndex.getOrderingIndex();
      //Add invalid idlist ids to both equality and ordering indexes.
      DatabaseEntry key=
           new DatabaseEntry(StaticUtils.getBytes("user.0@example.com"));