From 89485d11a14d27f7b0578695d436335de8bc58bd Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 10 Nov 2014 14:09:13 +0000
Subject: [PATCH] OPENDJ-1591 (CR-5206) Switch to SDK matching rules
---
opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java | 672 ++++++++++++++++++++++++-------------------------------
1 files changed, 297 insertions(+), 375 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index 978f519..1e8ea08 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -38,13 +38,13 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
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.IndexType;
import org.opends.server.admin.std.server.LocalDBIndexCfg;
-import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.monitors.DatabaseEnvironmentMonitor;
import org.opends.server.types.*;
@@ -76,16 +76,41 @@
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+ /** Type of the index filter. */
+ static enum IndexFilterType
+ {
+ /** Equality. */
+ EQUALITY(IndexType.EQUALITY),
+ /** Presence. */
+ PRESENCE(IndexType.PRESENCE),
+ /** Ordering. */
+ GREATER_OR_EQUAL(IndexType.ORDERING),
+ /** Ordering. */
+ LESS_OR_EQUAL(IndexType.ORDERING),
+ /** Substring. */
+ SUBSTRING(IndexType.SUBSTRING),
+ /** Approximate. */
+ APPROXIMATE(IndexType.APPROXIMATE);
+
+ private final IndexType indexType;
+
+ private IndexFilterType(IndexType indexType)
+ {
+ this.indexType = indexType;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString()
+ {
+ return indexType.toString();
+ }
+ }
+
/*
* 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...
+ * revisit this class. All of the evaluateXXX methods should go (the Matcher
+ * class in the SDK could implement the logic, I hope).
*/
/**
@@ -142,41 +167,17 @@
final int indexEntryLimit = indexConfig.getIndexEntryLimit();
final JEIndexConfig config = new JEIndexConfig(indexConfig.getSubstringLength());
- if (indexConfig.getIndexType().contains(IndexType.EQUALITY))
- {
- Index equalityIndex = buildExtIndex(name, attrType, indexEntryLimit,
- attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
- nameToIndexes.put(IndexType.EQUALITY.toString(), equalityIndex);
- }
-
if (indexConfig.getIndexType().contains(IndexType.PRESENCE))
{
- Index presenceIndex = newIndex(name + "." + IndexType.PRESENCE.toString(),
- indexEntryLimit, new PresenceIndexer(attrType));
- nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
+ String indexID = IndexType.PRESENCE.toString();
+ String indexName = name + "." + indexID;
+ Index presenceIndex = newIndex(indexName, indexEntryLimit, new PresenceIndexer(attrType));
+ nameToIndexes.put(indexID, presenceIndex);
}
-
- if (indexConfig.getIndexType().contains(IndexType.SUBSTRING))
- {
- Index substringIndex = buildExtIndex(name, attrType, indexEntryLimit,
- attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType));
- nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
- }
-
- if (indexConfig.getIndexType().contains(IndexType.ORDERING))
- {
- Index orderingIndex = buildExtIndex(name, attrType, indexEntryLimit,
- attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
- nameToIndexes.put(IndexType.ORDERING.toString(), orderingIndex);
- }
-
- if (indexConfig.getIndexType().contains(IndexType.APPROXIMATE))
- {
- Index approximateIndex = buildExtIndex(name, attrType, indexEntryLimit,
- attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
- nameToIndexes.put(IndexType.APPROXIMATE.toString(), approximateIndex);
- }
-
+ buildIndexes(indexConfig, attrType, name, IndexType.EQUALITY);
+ buildIndexes(indexConfig, attrType, name, IndexType.SUBSTRING);
+ buildIndexes(indexConfig, attrType, name, IndexType.ORDERING);
+ buildIndexes(indexConfig, attrType, name, IndexType.APPROXIMATE);
if (indexConfig.getIndexType().contains(IndexType.EXTENSIBLE))
{
@@ -205,8 +206,7 @@
if (!nameToIndexes.containsKey(indexId))
{
//There is no index available for this index id. Create a new index.
- final String indexName = name + "." + indexId;
- final Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
+ final Index extIndex = newExtensibleIndex(attrType, name, indexEntryLimit, indexer);
nameToIndexes.put(indexId, extIndex);
}
}
@@ -219,28 +219,52 @@
private Index newIndex(String indexName, int indexEntryLimit, Indexer indexer)
{
- return new Index(indexName, indexer, state, indexEntryLimit,
- cursorEntryLimit, false, env, entryContainer);
+ return new Index(indexName, indexer, state, indexEntryLimit, cursorEntryLimit, false, env, entryContainer);
}
- private Index buildExtIndex(String name, AttributeType attrType,
- int indexEntryLimit, MatchingRule rule, org.forgerock.opendj.ldap.spi.Indexer extIndexer) throws ConfigException
+ private void buildIndexes(LocalDBIndexCfg cfg, AttributeType attrType, String name, IndexType indexType)
+ throws ConfigException
{
- if (rule == null)
+ if (cfg.getIndexType().contains(indexType))
{
- throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(
- attrType, extIndexer.getIndexID()));
- }
+ final String indexID = indexType.toString();
+ final MatchingRule rule = getMatchingRule(indexType, attrType);
+ if (rule == null)
+ {
+ throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, indexID));
+ }
- final String indexName = name + "." + extIndexer.getIndexID();
- return newExtensibleIndex(indexName, attrType, indexEntryLimit, extIndexer);
+ for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
+ {
+ final Index index = newExtensibleIndex(attrType, name, cfg.getIndexEntryLimit(), indexer);
+ nameToIndexes.put(indexID, index);
+ }
+ }
}
- private Index newExtensibleIndex(String indexName, AttributeType attrType,
- int indexEntryLimit, org.forgerock.opendj.ldap.spi.Indexer extIndexer)
+ private MatchingRule getMatchingRule(IndexType indexType, AttributeType attrType)
{
- JEExtensibleIndexer indexer = new JEExtensibleIndexer(attrType, extIndexer);
- return newIndex(indexName, indexEntryLimit, indexer);
+ switch (indexType)
+ {
+ case APPROXIMATE:
+ return attrType.getApproximateMatchingRule();
+ case EQUALITY:
+ return attrType.getEqualityMatchingRule();
+ case ORDERING:
+ return attrType.getOrderingMatchingRule();
+ case SUBSTRING:
+ return attrType.getSubstringMatchingRule();
+ default:
+ throw new IllegalArgumentException("Not implemented for index type " + indexType);
+ }
+ }
+
+ private Index newExtensibleIndex(AttributeType attrType, String name, final int indexEntryLimit,
+ org.forgerock.opendj.ldap.spi.Indexer indexer)
+ {
+ final String indexName = name + "." + indexer.getIndexID();
+ final JEExtensibleIndexer extIndexer = new JEExtensibleIndexer(attrType, indexer);
+ return newIndex(indexName, indexEntryLimit, extIndexer);
}
/**
@@ -540,138 +564,6 @@
}
/**
- * Retrieve the entry IDs that might match an equality filter.
- *
- * @param equalityFilter The equality filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @return The candidate entry IDs that might contain the filter
- * assertion value.
- */
- public EntryIDSet evaluateEqualityFilter(SearchFilter equalityFilter, StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
- {
- try {
- final MatchingRule matchRule = equalityFilter.getAttributeType().getEqualityMatchingRule();
- final IndexQuery indexQuery = matchRule.getAssertion(equalityFilter.getAssertionValue())
- .createIndexQuery(indexQueryFactory);
- return evaluateIndexQuery(indexQuery, "equality", equalityFilter, debugBuffer, monitor);
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return new EntryIDSet();
- }
- }
-
- /**
- * Retrieve the entry IDs that might match a presence filter.
- *
- * @param filter The presence filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @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)
- {
- final IndexQuery indexQuery = indexQueryFactory.createMatchAllQuery();
- return evaluateIndexQuery(indexQuery, "presence", filter, debugBuffer, monitor);
- }
-
- /**
- * Retrieve the entry IDs that might match a greater-or-equal filter.
- *
- * @param filter The greater-or-equal filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @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,
- DatabaseEnvironmentMonitor monitor)
- {
- return evaluateOrderingFilter(filter, true, debugBuffer, monitor);
- }
-
-
- /**
- * Retrieve the entry IDs that might match a less-or-equal filter.
- *
- * @param filter The less-or-equal filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @return The candidate entry IDs that might contain a value
- * less than or equal to the filter assertion value.
- */
- public EntryIDSet evaluateLessOrEqualFilter(SearchFilter filter, StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
- {
- return evaluateOrderingFilter(filter, false, debugBuffer, monitor);
- }
-
- private EntryIDSet evaluateOrderingFilter(SearchFilter filter, boolean greater, StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
- {
- try {
- final MatchingRule matchRule = filter.getAttributeType().getOrderingMatchingRule();
- final Assertion assertion = greater ?
- matchRule.getGreaterOrEqualAssertion(filter.getAssertionValue()) :
- matchRule.getLessOrEqualAssertion(filter.getAssertionValue());
- final IndexQuery indexQuery = assertion.createIndexQuery(indexQueryFactory);
- return evaluateIndexQuery(indexQuery, "ordering", filter, debugBuffer, monitor);
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return new EntryIDSet();
- }
- }
-
- /**
- * Retrieve the entry IDs that might match a substring filter.
- *
- * @param filter The substring filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @return The candidate entry IDs that might contain a value
- * that matches the filter substrings.
- */
- public EntryIDSet evaluateSubstringFilter(SearchFilter filter,
- StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
- {
- try {
- final MatchingRule matchRule = filter.getAttributeType().getSubstringMatchingRule();
- final IndexQuery indexQuery = matchRule.getSubstringAssertion(
- filter.getSubInitialElement(), filter.getSubAnyElements(), filter.getSubFinalElement())
- .createIndexQuery(indexQueryFactory);
- return evaluateIndexQuery(indexQuery, "substring", filter, debugBuffer, monitor);
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return new EntryIDSet();
- }
- }
-
- /**
* Retrieve the entry IDs that might match two filters that restrict a value
* to both a lower bound and an upper bound.
*
@@ -695,20 +587,91 @@
{
// TODO : this implementation is not optimal
// as it implies two separate evaluations instead of a single one,
- // thus defeating the purpose of the optimisation done
+ // thus defeating the purpose of the optimization done
// in IndexFilter#evaluateLogicalAndFilter method.
// One solution could be to implement a boundedRangeAssertion that combine
// the two operations in one.
- EntryIDSet results = filter1.getFilterType() == FilterType.LESS_OR_EQUAL ?
- evaluateLessOrEqualFilter(filter1, debugBuffer, monitor) :
- evaluateGreaterOrEqualFilter(filter1, debugBuffer, monitor);
- EntryIDSet results2 = filter2.getFilterType() == FilterType.LESS_OR_EQUAL ?
- evaluateLessOrEqualFilter(filter2, debugBuffer, monitor) :
- evaluateGreaterOrEqualFilter(filter2, debugBuffer, monitor);
+ EntryIDSet results = evaluate(filter1, debugBuffer, monitor);
+ EntryIDSet results2 = evaluate(filter2, debugBuffer, monitor);
results.retainAll(results2);
return results;
}
+ private EntryIDSet evaluate(SearchFilter filter, StringBuilder debugBuffer, DatabaseEnvironmentMonitor monitor)
+ {
+ boolean isLessOrEqual = filter.getFilterType() == FilterType.LESS_OR_EQUAL;
+ IndexFilterType indexFilterType = isLessOrEqual ? IndexFilterType.LESS_OR_EQUAL : IndexFilterType.GREATER_OR_EQUAL;
+ return evaluateFilter(indexFilterType, filter, debugBuffer, monitor);
+ }
+
+ /**
+ * Retrieve the entry IDs that might match a filter.
+ *
+ * @param indexFilterType the index type filter
+ * @param filter The filter.
+ * @param debugBuffer If not null, a diagnostic string will be written
+ * which will help determine how the indexes contributed
+ * to this search.
+ * @param monitor The database environment monitor provider that will keep
+ * index filter usage statistics.
+ * @return The candidate entry IDs that might contain a value
+ * that matches the filter type.
+ */
+ public EntryIDSet evaluateFilter(IndexFilterType indexFilterType, SearchFilter filter, StringBuilder debugBuffer,
+ DatabaseEnvironmentMonitor monitor)
+ {
+ try
+ {
+ final IndexQuery indexQuery = getIndexQuery(indexFilterType, filter);
+ return evaluateIndexQuery(indexQuery, indexFilterType.toString(), filter, debugBuffer, monitor);
+ }
+ catch (DecodeException e)
+ {
+ logger.traceException(e);
+ return new EntryIDSet();
+ }
+ }
+
+ private IndexQuery getIndexQuery(IndexFilterType indexFilterType, SearchFilter filter) throws DecodeException
+ {
+ MatchingRule rule;
+ Assertion assertion;
+ switch (indexFilterType)
+ {
+ case EQUALITY:
+ rule = filter.getAttributeType().getEqualityMatchingRule();
+ assertion = rule.getAssertion(filter.getAssertionValue());
+ return assertion.createIndexQuery(indexQueryFactory);
+
+ case PRESENCE:
+ return indexQueryFactory.createMatchAllQuery();
+
+ case GREATER_OR_EQUAL:
+ rule = filter.getAttributeType().getOrderingMatchingRule();
+ assertion = rule.getGreaterOrEqualAssertion(filter.getAssertionValue());
+ return assertion.createIndexQuery(indexQueryFactory);
+
+ case LESS_OR_EQUAL:
+ rule = filter.getAttributeType().getOrderingMatchingRule();
+ assertion = rule.getLessOrEqualAssertion(filter.getAssertionValue());
+ return assertion.createIndexQuery(indexQueryFactory);
+
+ case SUBSTRING:
+ rule = filter.getAttributeType().getSubstringMatchingRule();
+ assertion = rule.getSubstringAssertion(
+ filter.getSubInitialElement(), filter.getSubAnyElements(), filter.getSubFinalElement());
+ return assertion.createIndexQuery(indexQueryFactory);
+
+ case APPROXIMATE:
+ rule = filter.getAttributeType().getApproximateMatchingRule();
+ assertion = rule.getAssertion(filter.getAssertionValue());
+ return assertion.createIndexQuery(indexQueryFactory);
+
+ default:
+ return null;
+ }
+ }
+
/**
* The default lexicographic byte array comparator.
* Is there one available in the Java platform?
@@ -804,34 +767,6 @@
}
/**
- * Retrieve the entry IDs that might match an approximate filter.
- *
- * @param approximateFilter The approximate filter.
- * @param debugBuffer If not null, a diagnostic string will be written
- * which will help determine how the indexes contributed
- * to this search.
- * @param monitor The database environment monitor provider that will keep
- * index filter usage statistics.
- * @return The candidate entry IDs that might contain the filter
- * assertion value.
- */
- public EntryIDSet evaluateApproximateFilter(SearchFilter approximateFilter, StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
- {
- try {
- MatchingRule matchRule = approximateFilter.getAttributeType().getApproximateMatchingRule();
- IndexQuery indexQuery = matchRule.getAssertion(approximateFilter.getAssertionValue())
- .createIndexQuery(indexQueryFactory);
- return evaluateIndexQuery(indexQuery, "approximate", approximateFilter, debugBuffer, monitor);
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return new EntryIDSet();
- }
- }
-
- /**
* Close cursors related to the attribute indexes.
*
* @throws DatabaseException If a database error occurs.
@@ -884,36 +819,15 @@
public synchronized boolean isConfigurationChangeAcceptable(
LocalDBIndexCfg cfg, List<LocalizableMessage> unacceptableReasons)
{
- AttributeType attrType = cfg.getAttribute();
+ if (!isIndexAcceptable(cfg, IndexType.EQUALITY, unacceptableReasons)
+ || !isIndexAcceptable(cfg, IndexType.SUBSTRING, unacceptableReasons)
+ || !isIndexAcceptable(cfg, IndexType.ORDERING, unacceptableReasons)
+ || !isIndexAcceptable(cfg, IndexType.APPROXIMATE, unacceptableReasons))
+ {
+ return false;
+ }
- 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(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(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(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;
- }
+ AttributeType attrType = cfg.getAttribute();
if (cfg.getIndexType().contains(IndexType.EXTENSIBLE))
{
Set<String> newRules = cfg.getIndexExtensibleMatchingRule();
@@ -923,14 +837,27 @@
return false;
}
}
+ return true;
+ }
+ private 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));
+ return false;
+ }
return true;
}
/** {@inheritDoc} */
@Override
- public synchronized ConfigChangeResult applyConfigurationChange(
- LocalDBIndexCfg cfg)
+ public synchronized ConfigChangeResult applyConfigurationChange(LocalDBIndexCfg cfg)
{
// this method is not perf sensitive, using an AtomicBoolean will not hurt
AtomicBoolean adminActionRequired = new AtomicBoolean(false);
@@ -939,91 +866,13 @@
{
AttributeType attrType = cfg.getAttribute();
String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
- final int indexEntryLimit = cfg.getIndexEntryLimit();
- 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", indexEntryLimit, presenceIndexer);
- openIndex(presenceIndex, adminActionRequired, messages);
- nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
- }
- else
- {
- // already exists. Just update index entry limit.
- if (presenceIndex.setIndexEntryLimit(indexEntryLimit))
- {
- adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(presenceIndex.getName()));
- }
- }
- }
- else
- {
- removeIndex(presenceIndex, IndexType.PRESENCE);
- }
-
- applyChangeToIndex(cfg, attrType, name, IndexType.EQUALITY,
- new EqualityIndexer(attrType), adminActionRequired, messages);
- applyChangeToIndex(cfg, attrType, name, IndexType.SUBSTRING,
- new SubstringIndexer(attrType), adminActionRequired, messages);
- 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(IndexType.EXTENSIBLE))
- {
- final Set<String> extensibleRules = cfg.getIndexExtensibleMatchingRule();
- final Set<MatchingRule> validRules = new HashSet<MatchingRule>();
- final Set<String> validIndexIds = new HashSet<String>();
-
- 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))
- {
- String indexName = name + "." + indexId;
- Index extIndex = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
- nameToIndexes.put(indexId, extIndex);
- openIndex(extIndex, adminActionRequired, messages);
- }
- else
- {
- Index extensibleIndex = nameToIndexes.get(indexId);
- if (extensibleIndex.setIndexEntryLimit(indexEntryLimit))
- {
- adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(extensibleIndex.getName()));
- }
- if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
- {
- extensibleIndex.setIndexer(new JEExtensibleIndexer(attrType, indexer));
- }
- }
- }
- }
- removeIndexesForExtensibleMatchingRules(validRules, validIndexIds);
- }
- else
- {
- final Set<MatchingRule> validRules = Collections.emptySet();
- final Set<String> validIndexIds = Collections.emptySet();
- removeIndexesForExtensibleMatchingRules(validRules, validIndexIds);
- }
+ applyChangeToPresenceIndex(cfg, attrType, name, adminActionRequired, messages);
+ applyChangeToIndex(cfg, attrType, name, IndexType.EQUALITY, adminActionRequired, messages);
+ applyChangeToIndex(cfg, attrType, name, IndexType.SUBSTRING, adminActionRequired, messages);
+ applyChangeToIndex(cfg, attrType, name, IndexType.ORDERING, adminActionRequired, messages);
+ applyChangeToIndex(cfg, attrType, name, IndexType.APPROXIMATE, adminActionRequired, messages);
+ applyChangeToExtensibleIndexes(cfg, attrType, name, adminActionRequired, messages);
extensibleIndexesMapping = computeExtensibleIndexesMapping();
indexConfig = cfg;
@@ -1038,6 +887,59 @@
}
}
+ private void applyChangeToExtensibleIndexes(LocalDBIndexCfg cfg, AttributeType attrType,
+ String name, AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
+ {
+ 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 extIndex = newExtensibleIndex(attrType, name, indexEntryLimit, indexer);
+ openIndex(extIndex, adminActionRequired, messages);
+ nameToIndexes.put(indexId, extIndex);
+ }
+ else
+ {
+ Index extensibleIndex = nameToIndexes.get(indexId);
+ if (extensibleIndex.setIndexEntryLimit(indexEntryLimit))
+ {
+ adminActionRequired.set(true);
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(extensibleIndex.getName()));
+ }
+ if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
+ {
+ extensibleIndex.setIndexer(new JEExtensibleIndexer(attrType, indexer));
+ }
+ }
+ }
+ }
+ removeIndexesForExtensibleMatchingRules(validRules, validIndexIds);
+ }
+
/** Remove indexes which do not correspond to valid rules. */
private void removeIndexesForExtensibleMatchingRules(Set<MatchingRule> validRules, Set<String> validIndexIds)
{
@@ -1092,34 +994,67 @@
return rules;
}
- private void applyChangeToIndex(LocalDBIndexCfg cfg, AttributeType attrType,
- String name, IndexType indexType, org.forgerock.opendj.ldap.spi.Indexer indexer,
+ private void applyChangeToIndex(LocalDBIndexCfg cfg, AttributeType attrType, String name, IndexType indexType,
AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
{
- final int indexEntryLimit = cfg.getIndexEntryLimit();
-
- Index index = nameToIndexes.get(indexType.toString());
- if (cfg.getIndexType().contains(indexType))
+ String indexId = indexType.toString();
+ Index index = nameToIndexes.get(indexId);
+ if (!cfg.getIndexType().contains(indexType))
{
- if (index == null)
+ removeIndex(index, indexType);
+ return;
+ }
+
+ final int indexEntryLimit = cfg.getIndexEntryLimit();
+ if (index == null)
+ {
+ final MatchingRule matchingRule = getMatchingRule(indexType, attrType);
+ for (org.forgerock.opendj.ldap.spi.Indexer indexer : matchingRule.getIndexers())
{
- 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()));
- }
+ index = newExtensibleIndex(attrType, name, indexEntryLimit, indexer);
+ openIndex(index, adminActionRequired, messages);
+ nameToIndexes.put(indexId, 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()));
+ }
+ }
+ }
+
+ private void applyChangeToPresenceIndex(LocalDBIndexCfg cfg, AttributeType attrType, String name,
+ AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
+ {
+ IndexType indexType = IndexType.PRESENCE;
+ String indexId = indexType.toString();
+ Index index = nameToIndexes.get(indexId);
+ if (!cfg.getIndexType().contains(indexType))
+ {
removeIndex(index, indexType);
+ return;
+ }
+
+ final int indexEntryLimit = cfg.getIndexEntryLimit();
+ if (index == null)
+ {
+ Indexer presenceIndexer = new PresenceIndexer(attrType);
+ index = newIndex(name + ".presence", indexEntryLimit, presenceIndexer);
+ openIndex(index, adminActionRequired, messages);
+ nameToIndexes.put(indexId, 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()));
+ }
}
}
@@ -1140,17 +1075,7 @@
}
}
- private Index openNewIndex(String name, AttributeType attrType,
- int indexEntryLimit, org.forgerock.opendj.ldap.spi.Indexer indexer,
- AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
- {
- final String indexName = name + "." + indexer.getIndexID();
- Index index = newExtensibleIndex(indexName, attrType, indexEntryLimit, indexer);
- return openIndex(index, adminActionRequired, messages);
- }
-
- private Index openIndex(Index index, AtomicBoolean adminActionRequired,
- ArrayList<LocalizableMessage> messages)
+ private void openIndex(Index index, AtomicBoolean adminActionRequired, ArrayList<LocalizableMessage> messages)
{
index.open();
@@ -1159,7 +1084,6 @@
adminActionRequired.set(true);
messages.add(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD.get(index.getName()));
}
- return index;
}
/**
@@ -1347,7 +1271,7 @@
|| matchRuleOID.equalsIgnoreCase(eqRule.getNameOrOID()))
{
//No matching rule is defined; use the default equality matching rule.
- return evaluateEqualityFilter(filter, debugBuffer, monitor);
+ return evaluateFilter(IndexFilterType.EQUALITY, filter, debugBuffer, monitor);
}
MatchingRule rule = DirectoryServer.getMatchingRule(matchRuleOID);
@@ -1401,16 +1325,14 @@
private boolean ruleHasAtLeasOneIndex(MatchingRule rule)
{
- boolean ruleHasAtLeastOneIndex = false;
for (org.forgerock.opendj.ldap.spi.Indexer indexer : rule.getIndexers())
{
if (nameToIndexes.containsKey(indexer.getIndexID()))
{
- ruleHasAtLeastOneIndex = true;
- break;
+ return true;
}
}
- return ruleHasAtLeastOneIndex;
+ return false;
}
/**
--
Gitblit v1.10.0