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

Jean-Noel Rouvignac
05.29.2014 e8053208c37ad81d6778f723a70f598d296437a0
OPENDJ-1602 (CR-5566) New pluggable storage based backend

Reduced coupling with JE.


AttributeIndex.java:
Removed thrown DatabaseException from constructor.
Moved newIndex(String, int, Indexer) to EntryContainer.
Removed now unnecessary fields and ctor parameters.
Extracted methods newPresenceIndex() and getIndexName().
Pushed index name creation down to where the index are actually created.
Removed many method parameters by directly passing the LocalDBIndexCfg down the method calls.

EntryContainer.java:
Moved AttributeIndex.newIndex(String, int, Indexer) here and renamed it newIndexForAttribute().
Changed all calls to AttributeIndex ctor.

DatabaseContainer.java
Removed thrown DatabaseException from constructor.
Code cleanup
3 files modified
200 ■■■■■ changed files
opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java 131 ●●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/backends/jeb/DatabaseContainer.java 47 ●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java 22 ●●●● patch | view | raw | blame | history
opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -54,7 +54,6 @@
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.Environment;
import static org.opends.messages.JebMessages.*;
import static org.opends.server.util.ServerConstants.*;
@@ -119,18 +118,14 @@
  /** The entryContainer in which this attribute index resides. */
  private final EntryContainer entryContainer;
  private final Environment env;
  private final State state;
  /** The attribute index configuration. */
  private LocalDBIndexCfg indexConfig;
  /** The mapping from names to indexes. */
  private final Map<String, Index> nameToIndexes;
  private final Map<String, Index> nameToIndexes = new HashMap<String, Index>();
  private final IndexQueryFactory<IndexQuery> indexQueryFactory;
  private final int cursorEntryLimit = 100000;
  /**
   * The mapping from extensible index types (e.g. "substring" or "shared") to list of indexes.
   */
@@ -139,53 +134,46 @@
  /**
   * Create a new attribute index object.
   *
   * @param entryContainer The entryContainer of this attribute index.
   * @param state The state database to persist index state info.
   * @param env The JE environment handle.
   * @param indexConfig The attribute index configuration.
   * @throws DatabaseException if a JE database error occurs.
   * @param entryContainer The entryContainer of this attribute index.
   * @throws ConfigException if a configuration related error occurs.
   */
  public AttributeIndex(LocalDBIndexCfg indexConfig, State state,
                        Environment env, EntryContainer entryContainer)
      throws DatabaseException, ConfigException
  public AttributeIndex(LocalDBIndexCfg indexConfig, EntryContainer entryContainer) throws ConfigException
  {
    this.entryContainer = entryContainer;
    this.env = env;
    this.indexConfig = indexConfig;
    this.state = state;
    nameToIndexes = new HashMap<String, Index>();
    AttributeType attrType = indexConfig.getAttribute();
    String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
    buildPresenceIndex(indexConfig, name);
    buildIndexes(IndexType.EQUALITY, indexConfig, name);
    buildIndexes(IndexType.SUBSTRING, indexConfig, name);
    buildIndexes(IndexType.ORDERING, indexConfig, name);
    buildIndexes(IndexType.APPROXIMATE, indexConfig, name);
    buildExtensibleIndexes(indexConfig, name);
    buildPresenceIndex();
    buildIndexes(IndexType.EQUALITY);
    buildIndexes(IndexType.SUBSTRING);
    buildIndexes(IndexType.ORDERING);
    buildIndexes(IndexType.APPROXIMATE);
    buildExtensibleIndexes();
    final JEIndexConfig config = new JEIndexConfig(indexConfig.getSubstringLength());
    indexQueryFactory = new IndexQueryFactoryImpl(nameToIndexes, config);
    extensibleIndexesMapping = computeExtensibleIndexesMapping();
  }
  private void buildPresenceIndex(LocalDBIndexCfg indexConfig, String name)
  private void buildPresenceIndex()
  {
    IndexType indexType = IndexType.PRESENCE;
    final IndexType indexType = IndexType.PRESENCE;
    if (indexConfig.getIndexType().contains(indexType))
    {
      final AttributeType attrType = indexConfig.getAttribute();
      final int indexEntryLimit = indexConfig.getIndexEntryLimit();
      String indexID = indexType.toString();
      String indexName = name + "." + indexID;
      Index presenceIndex = newIndex(indexName, indexEntryLimit, new PresenceIndexer(attrType));
      nameToIndexes.put(indexID, presenceIndex);
      nameToIndexes.put(indexID, newPresenceIndex(indexConfig));
    }
  }
  private void buildExtensibleIndexes(LocalDBIndexCfg indexConfig, String name) throws ConfigException
  private Index newPresenceIndex(LocalDBIndexCfg cfg)
  {
    final AttributeType attrType = cfg.getAttribute();
    final String indexName = getIndexName(attrType, IndexType.PRESENCE.toString());
    final PresenceIndexer indexer = new PresenceIndexer(attrType);
    return entryContainer.newIndexForAttribute(indexName, indexer, cfg.getIndexEntryLimit());
  }
  private void buildExtensibleIndexes() throws ConfigException
  {
    final IndexType indexType = IndexType.EXTENSIBLE;
    if (indexConfig.getIndexType().contains(indexType))
@@ -201,7 +189,6 @@
      // Collation equality and Ordering matching rules share the same indexer and index
      // A Collation substring matching rule is treated differently
      // as it uses a separate indexer and index.
      final int indexEntryLimit = indexConfig.getIndexEntryLimit();
      for (final String ruleName : extensibleRules)
      {
        MatchingRule rule = DirectoryServer.getMatchingRule(toLowerCase(ruleName));
@@ -216,22 +203,16 @@
          if (!nameToIndexes.containsKey(indexId))
          {
            // There is no index available for this index id. Create a new index
            final Index index = newAttributeIndex(attrType, name, indexEntryLimit, indexer);
            nameToIndexes.put(indexId, index);
            nameToIndexes.put(indexId, newAttributeIndex(indexConfig, indexer));
          }
        }
      }
    }
  }
  private Index newIndex(String indexName, int indexEntryLimit, Indexer indexer)
  private void buildIndexes(IndexType indexType) throws ConfigException
  {
    return new Index(indexName, indexer, state, indexEntryLimit, cursorEntryLimit, false, env, entryContainer);
  }
  private void buildIndexes(IndexType indexType, LocalDBIndexCfg cfg, String name) throws ConfigException
  {
    if (cfg.getIndexType().contains(indexType))
    if (indexConfig.getIndexType().contains(indexType))
    {
      final AttributeType attrType = indexConfig.getAttribute();
      final String indexID = indexType.toString();
@@ -243,8 +224,7 @@
      for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
      {
        final Index index = newAttributeIndex(attrType, name, cfg.getIndexEntryLimit(), indexer);
        nameToIndexes.put(indexID, index);
        nameToIndexes.put(indexID, newAttributeIndex(indexConfig, indexer));
      }
    }
  }
@@ -266,12 +246,17 @@
    }
  }
  private Index newAttributeIndex(AttributeType attrType, String name, final int indexEntryLimit,
      org.forgerock.opendj.ldap.spi.Indexer indexer)
  private Index newAttributeIndex(LocalDBIndexCfg indexConfig, org.forgerock.opendj.ldap.spi.Indexer indexer)
  {
    final String indexName = name + "." + indexer.getIndexID();
    final AttributeType attrType = indexConfig.getAttribute();
    final String indexName = getIndexName(attrType, indexer.getIndexID());
    final AttributeIndexer attrIndexer = new AttributeIndexer(attrType, indexer);
    return newIndex(indexName, indexEntryLimit, attrIndexer);
    return entryContainer.newIndexForAttribute(indexName, attrIndexer, indexConfig.getIndexEntryLimit());
  }
  private String getIndexName(AttributeType attrType, String indexID)
  {
    return entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID() + "." + indexID;
  }
  /**
@@ -709,15 +694,12 @@
    ArrayList<LocalizableMessage> messages = new ArrayList<LocalizableMessage>();
    try
    {
      AttributeType attrType = cfg.getAttribute();
      String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
      applyChangeToPresenceIndex(cfg, name, adminActionRequired, messages);
      applyChangeToIndex(IndexType.EQUALITY, cfg, name, adminActionRequired, messages);
      applyChangeToIndex(IndexType.SUBSTRING, cfg, name, adminActionRequired, messages);
      applyChangeToIndex(IndexType.ORDERING, cfg, name, adminActionRequired, messages);
      applyChangeToIndex(IndexType.APPROXIMATE, cfg, name, adminActionRequired, messages);
      applyChangeToExtensibleIndexes(cfg, attrType, name, adminActionRequired, messages);
      applyChangeToPresenceIndex(cfg, adminActionRequired, messages);
      applyChangeToIndex(IndexType.EQUALITY, cfg, adminActionRequired, messages);
      applyChangeToIndex(IndexType.SUBSTRING, cfg, adminActionRequired, messages);
      applyChangeToIndex(IndexType.ORDERING, cfg, adminActionRequired, messages);
      applyChangeToIndex(IndexType.APPROXIMATE, cfg, adminActionRequired, messages);
      applyChangeToExtensibleIndexes(cfg, adminActionRequired, messages);
      extensibleIndexesMapping = computeExtensibleIndexesMapping();
      indexConfig = cfg;
@@ -732,9 +714,10 @@
    }
  }
  private void applyChangeToExtensibleIndexes(LocalDBIndexCfg cfg, AttributeType attrType,
      String name, AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
  private void applyChangeToExtensibleIndexes(LocalDBIndexCfg cfg,
      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
  {
    final AttributeType attrType = cfg.getAttribute();
    if (!cfg.getIndexType().contains(IndexType.EXTENSIBLE))
    {
      final Set<MatchingRule> validRules = Collections.emptySet();
@@ -763,7 +746,7 @@
        validIndexIds.add(indexId);
        if (!nameToIndexes.containsKey(indexId))
        {
          Index index = newAttributeIndex(attrType, name, indexEntryLimit, indexer);
          Index index = newAttributeIndex(cfg, indexer);
          openIndex(index, adminActionRequired, messages);
          nameToIndexes.put(indexId, index);
        }
@@ -839,7 +822,7 @@
    return rules;
  }
  private void applyChangeToIndex(IndexType indexType, LocalDBIndexCfg cfg, String name,
  private void applyChangeToIndex(IndexType indexType, LocalDBIndexCfg cfg,
      AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
  {
    String indexId = indexType.toString();
@@ -850,14 +833,12 @@
      return;
    }
    final AttributeType attrType = cfg.getAttribute();
    final int indexEntryLimit = cfg.getIndexEntryLimit();
    if (index == null)
    {
      final MatchingRule matchingRule = getMatchingRule(indexType, attrType);
      final MatchingRule matchingRule = getMatchingRule(indexType, cfg.getAttribute());
      for (org.forgerock.opendj.ldap.spi.Indexer indexer : matchingRule.getIndexers())
      {
        index = newAttributeIndex(attrType, name, indexEntryLimit, indexer);
        index = newAttributeIndex(cfg, indexer);
        openIndex(index, adminActionRequired, messages);
        nameToIndexes.put(indexId, index);
      }
@@ -865,7 +846,7 @@
    else
    {
      // already exists. Just update index entry limit.
      if (index.setIndexEntryLimit(indexEntryLimit))
      if (index.setIndexEntryLimit(cfg.getIndexEntryLimit()))
      {
        adminActionRequired.set(true);
        messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
@@ -873,30 +854,28 @@
    }
  }
  private void applyChangeToPresenceIndex(LocalDBIndexCfg cfg, String name, AtomicBoolean adminActionRequired,
  private void applyChangeToPresenceIndex(LocalDBIndexCfg cfg, AtomicBoolean adminActionRequired,
      ArrayList<LocalizableMessage> messages)
  {
    IndexType indexType = IndexType.PRESENCE;
    String indexId = indexType.toString();
    Index index = nameToIndexes.get(indexId);
    final IndexType indexType = IndexType.PRESENCE;
    final String indexID = indexType.toString();
    Index index = nameToIndexes.get(indexID);
    if (!cfg.getIndexType().contains(indexType))
    {
      removeIndex(index, indexType);
      return;
    }
    final AttributeType attrType = cfg.getAttribute();
    final int indexEntryLimit = cfg.getIndexEntryLimit();
    if (index == null)
    {
      index = newIndex(name + "." + indexType, indexEntryLimit, new PresenceIndexer(attrType));
      index = newPresenceIndex(cfg);
      openIndex(index, adminActionRequired, messages);
      nameToIndexes.put(indexId, index);
      nameToIndexes.put(indexID, index);
    }
    else
    {
      // already exists. Just update index entry limit.
      if (index.setIndexEntryLimit(indexEntryLimit))
      if (index.setIndexEntryLimit(cfg.getIndexEntryLimit()))
      {
        adminActionRequired.set(true);
        messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
opendj3-server-dev/src/server/org/opends/server/backends/jeb/DatabaseContainer.java
@@ -42,30 +42,16 @@
{
  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
  /**
   * The database entryContainer.
   */
  protected EntryContainer entryContainer;
  /**
   * The JE database configuration.
   */
  protected DatabaseConfig dbConfig;
  /**
   * The name of the database within the entryContainer.
   */
  /** The database entryContainer. */
  protected final EntryContainer entryContainer;
  /** The name of the database within the entryContainer. */
  protected String name;
  /**
   * The reference to the JE Environment.
   */
  private Environment env;
  /**
   * A JE database handle opened through this database
   * container.
   */
  /** The JE database configuration. */
  protected DatabaseConfig dbConfig;
  /** The reference to the JE Environment. */
  private final Environment env;
  /** A JE database handle opened through this database container. */
  private Database database;
  /**
@@ -74,11 +60,8 @@
   * @param name The name of the entry database.
   * @param env The JE Environment.
   * @param entryContainer The entryContainer of the entry database.
   * @throws DatabaseException if a JE database error occurs.
   */
  protected DatabaseContainer(String name, Environment env,
                              EntryContainer entryContainer)
      throws DatabaseException
  protected DatabaseContainer(String name, Environment env, EntryContainer entryContainer)
  {
    this.env = env;
    this.entryContainer = entryContainer;
@@ -98,16 +81,13 @@
    if (dbConfig.getTransactional())
    {
      // Open the database under a transaction.
      Transaction txn =
          entryContainer.beginTransaction();
      Transaction txn = entryContainer.beginTransaction();
      try
      {
        database = env.openDatabase(txn, name, dbConfig);
        if (logger.isTraceEnabled())
        {
          logger.trace("JE database %s opened. txnid=%d",
                              database.getDatabaseName(),
                              txn.getId());
          logger.trace("JE database %s opened. txnid=%d", database.getDatabaseName(), txn.getId());
        }
        EntryContainer.transactionCommit(txn);
      }
@@ -122,8 +102,7 @@
      database = env.openDatabase(null, name, dbConfig);
      if (logger.isTraceEnabled())
      {
        logger.trace("JE database %s opened. txnid=none",
                            database.getDatabaseName());
        logger.trace("JE database %s opened. txnid=none", database.getDatabaseName());
      }
    }
  }
@@ -144,7 +123,7 @@
   * @throws DatabaseException if an error occurs.
   */
  @Override
  synchronized public void close() throws DatabaseException
  public synchronized void close() throws DatabaseException
  {
    if(dbConfig.getDeferredWrite())
    {
opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -153,7 +153,7 @@
      try
      {
        //Try creating all the indexes before confirming they are valid ones.
        new AttributeIndex(cfg, state, env, EntryContainer.this);
        new AttributeIndex(cfg, EntryContainer.this);
        return true;
      }
      catch(Exception e)
@@ -172,8 +172,7 @@
      try
      {
        AttributeIndex index =
          new AttributeIndex(cfg, state, env, EntryContainer.this);
        AttributeIndex index = new AttributeIndex(cfg, EntryContainer.this);
        index.open();
        if(!index.isTrusted())
        {
@@ -474,8 +473,7 @@
      {
        LocalDBIndexCfg indexCfg = config.getLocalDBIndex(idx);
        AttributeIndex index =
          new AttributeIndex(indexCfg, state, env, this);
        AttributeIndex index = new AttributeIndex(indexCfg, this);
        index.open();
        if(!index.isTrusted())
        {
@@ -3355,6 +3353,20 @@
    return index;
  }
  /**
   * Creates a new index for an attribute.
   *
   * @param indexName the name to give to the new index
   * @param indexer the indexer to use when inserting data into the index
   * @param indexEntryLimit the index entry limit
   * @return a new index
   */
  Index newIndexForAttribute(String indexName, Indexer indexer, int indexEntryLimit)
  {
    final int cursorEntryLimit = 100000;
    return new Index(indexName, indexer, state, indexEntryLimit, cursorEntryLimit, false, env, this);
  }
  /**
   * Checks if any modifications apply to this indexed attribute.