From 8ac57ee1cd50fcc3d02b36bea4ab1335924f1d7a Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <yannick.lecaillez@forgerock.com>
Date: Mon, 18 May 2015 13:52:40 +0000
Subject: [PATCH] OPENDJ-1864: Ordering matching rules should reuse equality indexes where possible
---
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/AttributeIndex.java | 568 ++++++++++++++++++--------------------------------------
1 files changed, 182 insertions(+), 386 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/AttributeIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/AttributeIndex.java
index 7396f2f..3a1dbb6 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/AttributeIndex.java
@@ -28,7 +28,6 @@
package org.opends.server.backends.jeb;
import static org.opends.messages.BackendMessages.*;
-import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.Closeable;
@@ -45,6 +44,7 @@
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
+import org.forgerock.opendj.ldap.spi.Indexer;
import org.forgerock.opendj.ldap.spi.IndexingOptions;
import org.forgerock.util.Utils;
import org.opends.server.admin.server.ConfigurationChangeListener;
@@ -116,15 +116,11 @@
/** The attribute index configuration. */
private LocalDBIndexCfg indexConfig;
+ private IndexingOptions indexingOptions;
/** The mapping from names to indexes. */
- private final Map<String, Index> nameToIndexes = new HashMap<String, Index>();
- private final IndexQueryFactory<IndexQuery> indexQueryFactory;
-
- /**
- * The mapping from extensible index types (e.g. "substring" or "shared") to list of indexes.
- */
- private Map<String, Collection<Index>> extensibleIndexesMapping;
+ private Map<String, Index> indexIdToIndexes;
+ private IndexQueryFactory<IndexQuery> indexQueryFactory;
/**
* Create a new attribute index object.
@@ -137,94 +133,119 @@
{
this.entryContainer = entryContainer;
this.indexConfig = indexConfig;
-
- 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, indexConfig.getAttribute());
- extensibleIndexesMapping = computeExtensibleIndexesMapping();
+ this.indexingOptions = new JEIndexingOptions(indexConfig.getSubstringLength());
+ this.indexIdToIndexes = Collections.unmodifiableMap(buildIndexes(entryContainer, indexConfig, indexingOptions));
+ this.indexQueryFactory = new IndexQueryFactoryImpl(indexIdToIndexes, indexingOptions, indexConfig.getAttribute());
}
- private void buildPresenceIndex()
+ private static Map<String, Index> buildIndexes(EntryContainer entryContainer,
+ LocalDBIndexCfg config,
+ IndexingOptions options) throws ConfigException
{
- final IndexType indexType = IndexType.PRESENCE;
- if (indexConfig.getIndexType().contains(indexType))
- {
- String indexID = indexType.toString();
- nameToIndexes.put(indexID, newPresenceIndex(indexConfig));
+ final Map<String, Index> indexes = new HashMap<>();
+ final AttributeType attributeType = config.getAttribute();
+ final int indexEntryLimit = config.getIndexEntryLimit();
+
+ for(IndexType indexType : config.getIndexType()) {
+ Collection<? extends Indexer> indexers;
+ switch (indexType)
+ {
+ case PRESENCE:
+ indexes.put(indexType.toString(), newPresenceIndex(entryContainer, config));
+ indexers = Collections.emptyList();
+ break;
+ case EXTENSIBLE:
+ indexers = getExtensibleIndexers(config.getAttribute(), config.getIndexExtensibleMatchingRule(), options);
+ break;
+ case APPROXIMATE:
+ indexers =
+ throwIfNoMatchingRule(attributeType, indexType, attributeType.getApproximateMatchingRule())
+ .createIndexers(options);
+ break;
+ case EQUALITY:
+ indexers =
+ throwIfNoMatchingRule(attributeType, indexType, attributeType.getEqualityMatchingRule())
+ .createIndexers(options);
+ break;
+ case ORDERING:
+ indexers =
+ throwIfNoMatchingRule(attributeType, indexType, attributeType.getOrderingMatchingRule())
+ .createIndexers(options);
+ break;
+ case SUBSTRING:
+ indexers =
+ throwIfNoMatchingRule(attributeType, indexType, attributeType.getSubstringMatchingRule())
+ .createIndexers(options);
+ break;
+ default:
+ throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attributeType, indexType.toString()));
+ }
+ buildAndRegisterIndexesWithIndexers(entryContainer, attributeType, indexEntryLimit, indexers, indexes);
}
+
+ return indexes;
}
- private Index newPresenceIndex(LocalDBIndexCfg cfg)
+ private static Index newPresenceIndex(EntryContainer entryContainer, LocalDBIndexCfg cfg)
{
final AttributeType attrType = cfg.getAttribute();
- final String indexName = getIndexName(attrType, IndexType.PRESENCE.toString());
+ final String indexName = getIndexName(entryContainer, attrType, IndexType.PRESENCE.toString());
final PresenceIndexer indexer = new PresenceIndexer(attrType);
return entryContainer.newIndexForAttribute(indexName, indexer, cfg.getIndexEntryLimit());
}
- private void buildExtensibleIndexes() throws ConfigException
+ private static MatchingRule throwIfNoMatchingRule(AttributeType attributeType, IndexType type, MatchingRule rule)
+ throws ConfigException
{
- final IndexType indexType = IndexType.EXTENSIBLE;
- if (indexConfig.getIndexType().contains(indexType))
+ if (rule == null)
{
- final AttributeType attrType = indexConfig.getAttribute();
- Set<String> extensibleRules = indexConfig.getIndexExtensibleMatchingRule();
- if (extensibleRules == null || extensibleRules.isEmpty())
- {
- throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, indexType.toString()));
- }
+ throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attributeType, type.toString()));
+ }
+ return rule;
+ }
- // Iterate through the Set and create the index only if necessary.
- // 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.
- for (final String ruleName : extensibleRules)
+ private static void buildAndRegisterIndexesWithIndexers(EntryContainer entryContainer,
+ AttributeType attributeType,
+ int indexEntryLimit,
+ Collection<? extends Indexer> indexers,
+ Map<String, Index> indexes)
+ {
+ for (Indexer indexer : indexers)
+ {
+ final String indexID = indexer.getIndexID();
+ if (!indexes.containsKey(indexID))
{
- MatchingRule rule = DirectoryServer.getMatchingRule(toLowerCase(ruleName));
- if (rule == null)
- {
- logger.error(ERR_CONFIG_INDEX_TYPE_NEEDS_VALID_MATCHING_RULE, attrType, ruleName);
- continue;
- }
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
- {
- final String indexId = indexer.getIndexID();
- if (!nameToIndexes.containsKey(indexId))
- {
- // There is no index available for this index id. Create a new index
- nameToIndexes.put(indexId, newAttributeIndex(indexConfig, indexer));
- }
- }
+ final Index index = newAttributeIndex(entryContainer, attributeType, indexer, indexEntryLimit);
+ indexes.put(indexID, index);
}
}
}
- private void buildIndexes(IndexType indexType) throws ConfigException
+ private static Collection<Indexer> getExtensibleIndexers(AttributeType attributeType, Set<String> extensibleRules,
+ IndexingOptions options) throws ConfigException
{
- if (indexConfig.getIndexType().contains(indexType))
+ if (extensibleRules == null || extensibleRules.isEmpty())
{
- final AttributeType attrType = indexConfig.getAttribute();
- final String indexID = indexType.toString();
- final MatchingRule rule = getMatchingRule(indexType, attrType);
+ throw new ConfigException(
+ ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attributeType, IndexType.EXTENSIBLE.toString()));
+ }
+
+ final Collection<Indexer> indexers = new ArrayList<>();
+ for (final String ruleName : extensibleRules)
+ {
+ final MatchingRule rule = DirectoryServer.getMatchingRule(toLowerCase(ruleName));
if (rule == null)
{
- throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, indexID));
+ logger.error(ERR_CONFIG_INDEX_TYPE_NEEDS_VALID_MATCHING_RULE, attributeType, ruleName);
+ continue;
}
-
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
- {
- nameToIndexes.put(indexID, newAttributeIndex(indexConfig, indexer));
- }
+ indexers.addAll(rule.createIndexers(options));
}
+
+ return indexers;
}
- private MatchingRule getMatchingRule(IndexType indexType, AttributeType attrType)
+ private static MatchingRule getMatchingRule(IndexType indexType, AttributeType attrType)
{
switch (indexType)
{
@@ -241,15 +262,15 @@
}
}
- private Index newAttributeIndex(LocalDBIndexCfg indexConfig, org.forgerock.opendj.ldap.spi.Indexer indexer)
+ private static Index newAttributeIndex(EntryContainer entryContainer, AttributeType attributeType,
+ org.forgerock.opendj.ldap.spi.Indexer indexer, int indexEntryLimit)
{
- final AttributeType attrType = indexConfig.getAttribute();
- final String indexName = getIndexName(attrType, indexer.getIndexID());
- final AttributeIndexer attrIndexer = new AttributeIndexer(attrType, indexer);
- return entryContainer.newIndexForAttribute(indexName, attrIndexer, indexConfig.getIndexEntryLimit());
+ final String indexName = getIndexName(entryContainer, attributeType, indexer.getIndexID());
+ final AttributeIndexer attrIndexer = new AttributeIndexer(attributeType, indexer);
+ return entryContainer.newIndexForAttribute(indexName, attrIndexer, indexEntryLimit);
}
- private String getIndexName(AttributeType attrType, String indexID)
+ private static String getIndexName(EntryContainer entryContainer, AttributeType attrType, String indexID)
{
return entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID() + "." + indexID;
}
@@ -262,7 +283,7 @@
*/
public void open() throws DatabaseException
{
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
index.open();
}
@@ -273,7 +294,7 @@
@Override
public void close()
{
- Utils.closeSilently(nameToIndexes.values());
+ Utils.closeSilently(indexIdToIndexes.values());
indexConfig.removeChangeListener(this);
// The entryContainer is responsible for closing the JE databases.
}
@@ -315,13 +336,11 @@
* @throws DatabaseException If an error occurs in the JE database.
* @throws DirectoryException If a Directory Server error occurs.
*/
- public void addEntry(IndexBuffer buffer, EntryID entryID, Entry entry)
- throws DatabaseException, DirectoryException
+ public void addEntry(IndexBuffer buffer, EntryID entryID, Entry entry) throws DatabaseException, DirectoryException
{
- final IndexingOptions options = indexQueryFactory.getIndexingOptions();
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
- index.addEntry(buffer, entryID, entry, options);
+ index.addEntry(buffer, entryID, entry);
}
}
@@ -337,10 +356,9 @@
public void removeEntry(IndexBuffer buffer, EntryID entryID, Entry entry)
throws DatabaseException, DirectoryException
{
- final IndexingOptions options = indexQueryFactory.getIndexingOptions();
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
- index.removeEntry(buffer, entryID, entry, options);
+ index.removeEntry(buffer, entryID, entry);
}
}
@@ -363,10 +381,9 @@
List<Modification> mods)
throws DatabaseException
{
- final IndexingOptions options = indexQueryFactory.getIndexingOptions();
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
- index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods, options);
+ index.modifyEntry(buffer, entryID, oldEntry, newEntry, mods);
}
}
@@ -379,7 +396,7 @@
* @param len The length of the substring.
* @return A byte string containing a substring key.
*/
- private ByteString makeSubstringKey(byte[] bytes, int pos, int len)
+ private static ByteString makeSubstringKey(byte[] bytes, int pos, int len)
{
byte[] keyBytes = new byte[len];
System.arraycopy(bytes, pos, keyBytes, 0, len);
@@ -602,7 +619,7 @@
{
long entryLimitExceededCount = 0;
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
entryLimitExceededCount += index.getEntryLimitExceededCount();
}
@@ -615,7 +632,7 @@
*/
public void listDatabases(List<DatabaseContainer> dbList)
{
- dbList.addAll(nameToIndexes.values());
+ dbList.addAll(indexIdToIndexes.values());
}
/**
@@ -654,16 +671,14 @@
return true;
}
- private boolean isIndexAcceptable(LocalDBIndexCfg cfg, IndexType indexType,
+ private static boolean isIndexAcceptable(LocalDBIndexCfg cfg, IndexType indexType,
List<LocalizableMessage> unacceptableReasons)
{
- final String indexId = indexType.toString();
final AttributeType attrType = cfg.getAttribute();
if (cfg.getIndexType().contains(indexType)
- && nameToIndexes.get(indexId) == null
&& getMatchingRule(indexType, attrType) == null)
{
- unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, indexId));
+ unacceptableReasons.add(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, indexType.toString()));
return false;
}
return true;
@@ -671,218 +686,61 @@
/** {@inheritDoc} */
@Override
- public synchronized ConfigChangeResult applyConfigurationChange(LocalDBIndexCfg cfg)
+ public synchronized ConfigChangeResult applyConfigurationChange(final LocalDBIndexCfg newConfiguration)
{
final ConfigChangeResult ccr = new ConfigChangeResult();
+ final IndexingOptions newIndexingOptions = new JEIndexingOptions(newConfiguration.getSubstringLength());
try
{
- applyChangeToPresenceIndex(cfg, ccr);
- applyChangeToIndex(IndexType.EQUALITY, cfg, ccr);
- applyChangeToIndex(IndexType.SUBSTRING, cfg, ccr);
- applyChangeToIndex(IndexType.ORDERING, cfg, ccr);
- applyChangeToIndex(IndexType.APPROXIMATE, cfg, ccr);
- applyChangeToExtensibleIndexes(cfg, ccr);
+ Map<String, Index> newIndexIdToIndexes = buildIndexes(entryContainer, newConfiguration, newIndexingOptions);
- extensibleIndexesMapping = computeExtensibleIndexesMapping();
- indexConfig = cfg;
+ final Map<String, Index> removedIndexes = new HashMap<>(indexIdToIndexes);
+ removedIndexes.keySet().removeAll(newIndexIdToIndexes.keySet());
- return ccr;
+ final Map<String, Index> addedIndexes = new HashMap<>(newIndexIdToIndexes);
+ addedIndexes.keySet().removeAll(indexIdToIndexes.keySet());
+
+ final Map<String, Index> updatedIndexes = new HashMap<>(indexIdToIndexes);
+ updatedIndexes.keySet().retainAll(newIndexIdToIndexes.keySet());
+
+ // Replace instances of Index created by buildIndexes() with the one already opened and present in the actual
+ // indexIdToIndexes
+ newIndexIdToIndexes.putAll(updatedIndexes);
+
+ // Open added indexes *before* adding them to indexIdToIndexes
+ for (Index addedIndex : addedIndexes.values())
+ {
+ openIndex(addedIndex, ccr);
+ }
+
+ indexConfig = newConfiguration;
+ indexingOptions = newIndexingOptions;
+ indexIdToIndexes = Collections.unmodifiableMap(newIndexIdToIndexes);
+ indexQueryFactory = new IndexQueryFactoryImpl(indexIdToIndexes, indexingOptions, indexConfig.getAttribute());
+
+ // FIXME: There is no guarantee here that deleted index are not currently involved in a query
+ for (Index removedIndex : removedIndexes.values())
+ {
+ deleteIndex(entryContainer, removedIndex);
+ }
+
+ for (Index updatedIndex : updatedIndexes.values())
+ {
+ updateIndex(updatedIndex, newConfiguration.getIndexEntryLimit(), ccr);
+ }
}
- catch(Exception e)
+ catch (Exception e)
{
ccr.setResultCode(DirectoryServer.getServerErrorResultCode());
ccr.addMessage(LocalizableMessage.raw(StaticUtils.stackTraceToSingleLineString(e)));
- return ccr;
}
+
+ return ccr;
}
- private void applyChangeToExtensibleIndexes(LocalDBIndexCfg cfg, final ConfigChangeResult ccr)
- {
- final AttributeType attrType = cfg.getAttribute();
- if (!cfg.getIndexType().contains(IndexType.EXTENSIBLE))
- {
- final Set<MatchingRule> validRules = Collections.emptySet();
- final Set<String> validIndexIds = Collections.emptySet();
- removeIndexesForExtensibleMatchingRules(validRules, validIndexIds);
- return;
- }
-
- final Set<String> extensibleRules = cfg.getIndexExtensibleMatchingRule();
- final Set<MatchingRule> validRules = new HashSet<MatchingRule>();
- final Set<String> validIndexIds = new HashSet<String>();
- final int indexEntryLimit = cfg.getIndexEntryLimit();
-
- for (String ruleName : extensibleRules)
- {
- MatchingRule rule = DirectoryServer.getMatchingRule(toLowerCase(ruleName));
- if (rule == null)
- {
- logger.error(ERR_CONFIG_INDEX_TYPE_NEEDS_VALID_MATCHING_RULE, attrType, ruleName);
- continue;
- }
- validRules.add(rule);
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
- {
- String indexId = indexer.getIndexID();
- validIndexIds.add(indexId);
- if (!nameToIndexes.containsKey(indexId))
- {
- Index index = newAttributeIndex(cfg, indexer);
- openIndex(index, ccr);
- nameToIndexes.put(indexId, index);
- }
- else
- {
- Index index = nameToIndexes.get(indexId);
- if (index.setIndexEntryLimit(indexEntryLimit))
- {
- ccr.setAdminActionRequired(true);
- ccr.addMessage(NOTE_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
- }
- if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
- {
- index.setIndexer(new AttributeIndexer(attrType, indexer));
- }
- }
- }
- }
- removeIndexesForExtensibleMatchingRules(validRules, validIndexIds);
- }
-
- /** Remove indexes which do not correspond to valid rules. */
- private void removeIndexesForExtensibleMatchingRules(Set<MatchingRule> validRules, Set<String> validIndexIds)
- {
- final Set<MatchingRule> rulesToDelete = getCurrentExtensibleMatchingRules();
- rulesToDelete.removeAll(validRules);
- if (!rulesToDelete.isEmpty())
- {
- entryContainer.exclusiveLock.lock();
- try
- {
- for (MatchingRule rule: rulesToDelete)
- {
- final List<String> indexIdsToRemove = new ArrayList<String>();
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
- {
- final String indexId = indexer.getIndexID();
- if (!validIndexIds.contains(indexId))
- {
- indexIdsToRemove.add(indexId);
- }
- }
- // Delete indexes which are not used
- for (String indexId : indexIdsToRemove)
- {
- Index index = nameToIndexes.get(indexId);
- if (index != null)
- {
- entryContainer.deleteDatabase(index);
- nameToIndexes.remove(index);
- }
- }
- }
- }
- finally
- {
- entryContainer.exclusiveLock.unlock();
- }
- }
- }
-
- private Set<MatchingRule> getCurrentExtensibleMatchingRules()
- {
- final Set<MatchingRule> rules = new HashSet<MatchingRule>();
- for (String ruleName : indexConfig.getIndexExtensibleMatchingRule())
- {
- final MatchingRule rule = DirectoryServer.getMatchingRule(toLowerCase(ruleName));
- if (rule != null)
- {
- rules.add(rule);
- }
- }
- return rules;
- }
-
- private void applyChangeToIndex(IndexType indexType, LocalDBIndexCfg cfg, final ConfigChangeResult ccr)
- {
- String indexId = indexType.toString();
- Index index = nameToIndexes.get(indexId);
- if (!cfg.getIndexType().contains(indexType))
- {
- removeIndex(index, indexType);
- return;
- }
-
- if (index == null)
- {
- final MatchingRule matchingRule = getMatchingRule(indexType, cfg.getAttribute());
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : matchingRule.getIndexers())
- {
- index = newAttributeIndex(cfg, indexer);
- openIndex(index, ccr);
- nameToIndexes.put(indexId, index);
- }
- }
- else
- {
- // already exists. Just update index entry limit.
- if (index.setIndexEntryLimit(cfg.getIndexEntryLimit()))
- {
- ccr.setAdminActionRequired(true);
- ccr.addMessage(NOTE_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
- }
- }
- }
-
- private void applyChangeToPresenceIndex(LocalDBIndexCfg cfg, final ConfigChangeResult ccr)
- {
- final IndexType indexType = IndexType.PRESENCE;
- final String indexID = indexType.toString();
- Index index = nameToIndexes.get(indexID);
- if (!cfg.getIndexType().contains(indexType))
- {
- removeIndex(index, indexType);
- return;
- }
-
- if (index == null)
- {
- index = newPresenceIndex(cfg);
- openIndex(index, ccr);
- nameToIndexes.put(indexID, index);
- }
- else
- {
- // already exists. Just update index entry limit.
- if (index.setIndexEntryLimit(cfg.getIndexEntryLimit()))
- {
- ccr.setAdminActionRequired(true);
- ccr.addMessage(NOTE_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(index.getName()));
- }
- }
- }
-
- 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 void openIndex(Index index, final ConfigChangeResult ccr)
+ private static void openIndex(Index index, ConfigChangeResult ccr)
{
index.open();
-
if (!index.isTrusted())
{
ccr.setAdminActionRequired(true);
@@ -890,13 +748,36 @@
}
}
+ private static void updateIndex(Index updatedIndex, int newIndexEntryLimit, ConfigChangeResult ccr)
+ {
+ if (updatedIndex.setIndexEntryLimit(newIndexEntryLimit))
+ {
+ // This index can still be used since index size limit doesn't impact validity of the results.
+ ccr.setAdminActionRequired(true);
+ ccr.addMessage(NOTE_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(updatedIndex.getName()));
+ }
+ }
+
+ private static void deleteIndex(EntryContainer entryContainer, Index index)
+ {
+ entryContainer.exclusiveLock.lock();
+ try
+ {
+ entryContainer.deleteDatabase(index);
+ }
+ finally
+ {
+ entryContainer.exclusiveLock.unlock();
+ }
+ }
+
/**
* Return true iff this index is trusted.
* @return the trusted state of this index
*/
public boolean isTrusted()
{
- for (Index index : nameToIndexes.values())
+ for (Index index : indexIdToIndexes.values())
{
if (!index.isTrusted())
{
@@ -918,103 +799,18 @@
+ indexConfig.getAttribute().getNameOrOID();
}
- /**
- * Return the equality index.
- *
- * @return The equality index.
- */
- public Index getEqualityIndex() {
- return nameToIndexes.get(IndexType.EQUALITY.toString());
- }
-
- /**
- * Return the approximate index.
- *
- * @return The approximate index.
- */
- public Index getApproximateIndex() {
- return nameToIndexes.get(IndexType.APPROXIMATE.toString());
- }
-
- /**
- * Return the ordering index.
- *
- * @return The ordering index.
- */
- public Index getOrderingIndex() {
- return nameToIndexes.get(IndexType.ORDERING.toString());
- }
-
- /**
- * Return the substring index.
- *
- * @return The substring index.
- */
- public Index getSubstringIndex() {
- return nameToIndexes.get(IndexType.SUBSTRING.toString());
- }
-
- /**
- * Return the presence index.
- *
- * @return The presence index.
- */
- public Index getPresenceIndex() {
- return nameToIndexes.get(IndexType.PRESENCE.toString());
- }
-
- /**
- * Return the mapping of extensible index types and indexes.
- *
- * @return The map containing entries (extensible index type, list of indexes)
- */
- public Map<String, Collection<Index>> getExtensibleIndexes()
- {
- return extensibleIndexesMapping;
- }
-
- private Map<String, Collection<Index>> computeExtensibleIndexesMapping()
- {
- final Collection<Index> substring = new ArrayList<Index>();
- final Collection<Index> shared = new ArrayList<Index>();
- for (Map.Entry<String, Index> entry : nameToIndexes.entrySet())
- {
- final String indexId = entry.getKey();
- if (isDefaultIndex(indexId)) {
- continue;
- }
- if (indexId.endsWith(EXTENSIBLE_INDEXER_ID_SUBSTRING))
- {
- substring.add(entry.getValue());
- }
- else
- {
- shared.add(entry.getValue());
- }
- }
- final Map<String, Collection<Index>> indexMap = new HashMap<String,Collection<Index>>();
- indexMap.put(EXTENSIBLE_INDEXER_ID_SUBSTRING, substring);
- indexMap.put(EXTENSIBLE_INDEXER_ID_SHARED, shared);
- return Collections.unmodifiableMap(indexMap);
- }
-
- private boolean isDefaultIndex(String indexId)
- {
- return indexId.equals(IndexType.EQUALITY.toString())
- || indexId.equals(IndexType.PRESENCE.toString())
- || indexId.equals(IndexType.SUBSTRING.toString())
- || indexId.equals(IndexType.ORDERING.toString())
- || indexId.equals(IndexType.APPROXIMATE.toString());
+ Index getIndex(String indexID) {
+ return indexIdToIndexes.get(indexID);
}
/**
* Retrieves all the indexes used by this attribute index.
*
- * @return A collection of all indexes in use by this attribute
+ * @return An immutable collection of all indexes in use by this attribute
* index.
*/
public Collection<Index> getAllIndexes() {
- return new LinkedHashSet<Index>(nameToIndexes.values());
+ return indexIdToIndexes.values();
}
/**
@@ -1065,7 +861,7 @@
if (debugBuffer != null)
{
debugBuffer.append("[INDEX:");
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
+ for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.createIndexers(indexingOptions))
{
debugBuffer.append(" ")
.append(filter.getAttributeType().getNameOrOID())
@@ -1100,9 +896,9 @@
private boolean ruleHasAtLeasOneIndex(MatchingRule rule)
{
- for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
+ for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.createIndexers(indexingOptions))
{
- if (nameToIndexes.containsKey(indexer.getIndexID()))
+ if (indexIdToIndexes.containsKey(indexer.getIndexID()))
{
return true;
}
@@ -1111,7 +907,7 @@
}
/** This class extends the IndexConfig for JE Backend. */
- private final class JEIndexConfig implements IndexingOptions
+ private static final class JEIndexingOptions implements IndexingOptions
{
/** The length of the substring index. */
private int substringLength;
@@ -1120,7 +916,7 @@
* Creates a new JEIndexConfig instance.
* @param substringLength The length of the substring.
*/
- private JEIndexConfig(int substringLength)
+ private JEIndexingOptions(int substringLength)
{
this.substringLength = substringLength;
}
--
Gitblit v1.10.0