From d45f3ef4848972f83705fede48872b8d91d68349 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Thu, 03 Apr 2014 13:53:49 +0000
Subject: [PATCH] Checkpoint commit for OPENDJ-1308 Migrate schema support
---
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/MatchingRule.java | 29
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java | 184 ++----
opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java | 11
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java | 41 +
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CertificateExactMatchingRule.java | 9
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/SearchFilter.java | 131 +--
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java | 14
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/SubstringMatchingRule.java | 66 --
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java | 53 +
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/ApproximateMatchingRule.java | 28
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java | 855 +++++-----------------------
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java | 23
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexFilter.java | 109 ---
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java | 94 ++-
opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java | 68 ++
15 files changed, 564 insertions(+), 1,151 deletions(-)
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
index c377a94..1a871cc 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/AbstractMatchingRule.java
@@ -52,6 +52,65 @@
public abstract class AbstractMatchingRule implements MatchingRule
{
+ /**
+ * Default implementation of assertion.
+ */
+ public static final class DefaultAssertion implements Assertion
+ {
+ /** The ID of the DB index to use with this assertion. */
+ private final String indexID;
+ private final ByteSequence normalizedAssertionValue;
+
+ /**
+ * Returns the equality assertion.
+ *
+ * @param normalizedAssertionValue
+ * The value on which the assertion is built.
+ * @return the equality assertion
+ */
+ public static DefaultAssertion equality(final ByteSequence normalizedAssertionValue)
+ {
+ return new DefaultAssertion("equality", normalizedAssertionValue);
+ }
+
+ /**
+ * Returns the approximate assertion.
+ *
+ * @param normalizedAssertionValue
+ * The value on which the assertion is built.
+ * @return the approximate assertion
+ */
+ static DefaultAssertion approximate(final ByteSequence normalizedAssertionValue)
+ {
+ return new DefaultAssertion("approximate", normalizedAssertionValue);
+ }
+
+ private DefaultAssertion(final String indexID, final ByteSequence normalizedAssertionValue)
+ {
+ this.indexID = indexID;
+ this.normalizedAssertionValue = normalizedAssertionValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ConditionResult matches(final ByteSequence normalizedAttributeValue)
+ {
+ return ConditionResult.valueOf(normalizedAssertionValue.equals(normalizedAttributeValue));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ return factory.createExactMatchQuery(indexID, normalizedAssertionValue);
+ }
+ }
+
private static final Assertion UNDEFINED_ASSERTION = new Assertion()
{
@Override
@@ -71,9 +130,14 @@
};
/**
- * {@inheritDoc}
+ * Returns the normalized form of the assertion value.
+ *
+ * @param value
+ * The assertion value to normalize.
+ * @return the normalized value
+ * @throws DecodeException
+ * If a problem occurs.
*/
- @Override
public ByteString normalizeAssertionValue(ByteSequence value)
throws DecodeException
{
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/ApproximateMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/ApproximateMatchingRule.java
index 1c530a3..93e114e 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/ApproximateMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/ApproximateMatchingRule.java
@@ -26,8 +26,12 @@
*/
package org.opends.server.api;
+import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
+import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ConditionResult;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
/**
* This class defines the set of methods and structures that must be
@@ -86,5 +90,29 @@
return ConditionResult.valueOf(
approximatelyMatch(attributeValue, assertionValue));
}
+
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(ByteSequence assertionValue) throws DecodeException
+ {
+ final ByteString normAssertionValue = normalizeAttributeValue(assertionValue);
+ final DefaultAssertion approxAssertion = DefaultAssertion.approximate(normAssertionValue);
+ return new Assertion()
+ {
+ @Override
+ public ConditionResult matches(ByteSequence normalizedAttributeValue)
+ {
+ return valuesMatch(normalizedAttributeValue, normAssertionValue);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ return approxAssertion.createIndexQuery(factory);
+ }
+ };
+ }
+
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
index 05a364e..81251f7 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/EqualityMatchingRule.java
@@ -26,8 +26,13 @@
*/
package org.opends.server.api;
+import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
+import org.forgerock.opendj.ldap.ByteString;
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
@@ -108,5 +113,41 @@
{
return attributeValue.hashCode();
}
+
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(ByteSequence assertionValue) throws DecodeException
+ {
+ final ByteString normAssertionValue = normalizeAttributeValue(assertionValue);
+ return getEqualityAssertion(normAssertionValue);
+ }
+
+ /**
+ * Return the equality assertion for the matching rule.
+ *
+ * @param normAssertionValue
+ * The normalized assertion value.
+ * @return the assertion
+ */
+ protected Assertion getEqualityAssertion(final ByteString normAssertionValue)
+ {
+ final DefaultAssertion eqAssertion = DefaultAssertion.equality(normAssertionValue);
+ return new Assertion()
+ {
+ @Override
+ public ConditionResult matches(ByteSequence normalizedAttributeValue)
+ {
+ return valuesMatch(normalizedAttributeValue, normAssertionValue);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory)
+ throws DecodeException
+ {
+ return eqAssertion.createIndexQuery(factory);
+ }
+ };
+ }
+
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/MatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/MatchingRule.java
index 0d3c9ee..e0aeb2a 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/MatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/MatchingRule.java
@@ -64,25 +64,6 @@
*/
String getOID();
-
-
- /**
- * Retrieves the normalized form of the provided assertion value,
- * which is best suite for efficiently performing matching
- * operations on that value.
- *
- * @param value
- * The assertion value to be normalized.
- * @return The normalized version of the provided value.
- * @throws DecodeException
- * If the provided value is invalid according to the
- * associated attribute syntax.
- */
- ByteString normalizeAssertionValue(ByteSequence value)
- throws DecodeException;
-
-
-
/**
* Retrieves the name or OID for this matching rule. If it has a
* name, then it will be returned. Otherwise, the OID will be
@@ -118,7 +99,7 @@
* @throws DecodeException
* if problem
*/
- Assertion getAssertion(final ByteSequence assertionValue) throws DecodeException;
+ Assertion getAssertion(ByteSequence assertionValue) throws DecodeException;
/**
* Returns the normalized form of the provided assertion value, which is
@@ -132,7 +113,7 @@
* @throws DecodeException
* if the syntax of the value is not valid.
*/
- public Assertion getGreaterOrEqualAssertion(final ByteSequence assertionValue) throws DecodeException;
+ Assertion getGreaterOrEqualAssertion(ByteSequence assertionValue) throws DecodeException;
/**
* Returns the normalized form of the provided assertion value, which is
@@ -146,7 +127,7 @@
* @throws DecodeException
* if the syntax of the value is not valid.
*/
- public Assertion getLessOrEqualAssertion(final ByteSequence assertionValue) throws DecodeException;
+ Assertion getLessOrEqualAssertion(ByteSequence assertionValue) throws DecodeException;
/**
* Returns the normalized form of the provided assertion substring values,
@@ -166,8 +147,8 @@
* @throws DecodeException
* if the syntax of the value is not valid.
*/
- public Assertion getSubstringAssertion(final ByteSequence subInitial,
- final List<? extends ByteSequence> subAnyElements, final ByteSequence subFinal) throws DecodeException;
+ Assertion getSubstringAssertion(ByteSequence subInitial, List<? extends ByteSequence> subAnyElements,
+ ByteSequence subFinal) throws DecodeException;
/**
* Indicates whether this matching rule is declared "OBSOLETE". The
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/SubstringMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/SubstringMatchingRule.java
index b3d84fb..8eaec37 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/SubstringMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/api/SubstringMatchingRule.java
@@ -345,72 +345,6 @@
}
}
- // TODO : reminder : should add this method in the SDK
- /** {@inheritDoc} */
- @Override
- public int hashCode()
- {
- int hashCode = 0;
- if (normInitial != null)
- {
- hashCode += normInitial.hashCode();
- }
- if (normAnys != null)
- {
- for (ByteString any : normAnys)
- {
- hashCode += any.hashCode();
- }
- }
- if (normFinal != null)
- {
- hashCode += normFinal.hashCode();
- }
- return hashCode;
- }
-
- // TODO : reminder : should add this method in the SDK
- /** {@inheritDoc} */
- @Override
- public boolean equals(Object obj)
- {
- if (obj == this)
- {
- return true;
- }
- if (! (obj instanceof DefaultSubstringAssertion))
- {
- return false;
- }
- DefaultSubstringAssertion other = (DefaultSubstringAssertion) obj;
- boolean initialCheck = normInitial == null ? other.normInitial == null : normInitial.equals(other.normInitial);
- if (!initialCheck)
- {
- return false;
- }
- boolean finalCheck = normFinal == null ? other.normFinal == null : normFinal.equals(other.normFinal);
- if (!finalCheck)
- {
- return false;
- }
- boolean anyCheck = normAnys == null ? other.normAnys == null : normAnys.length == other.normAnys.length;
- if (!anyCheck)
- {
- return false;
- }
- if (normAnys != null)
- {
- for (int i = 0; i < normAnys.length; i++)
- {
- if (! normAnys[i].equals(other.normAnys[i]))
- {
- return false;
- }
- }
- }
- return true;
- }
-
}
/** {@inheritDoc} */
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index cb1e32d..fb3a6a8 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -31,8 +31,10 @@
import java.util.concurrent.atomic.AtomicBoolean;
import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ResultCode;
@@ -41,11 +43,11 @@
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;
import org.opends.server.api.ExtensibleMatchingRule;
import org.opends.server.api.MatchingRule;
-import org.opends.server.api.SubstringMatchingRule;
import org.opends.server.core.DirectoryServer;
import org.opends.server.monitors.DatabaseEnvironmentMonitor;
import org.opends.server.types.*;
@@ -119,6 +121,11 @@
*/
Index approximateIndex = null;
+ /** The mapping from names to indexes. */
+ private Map<String, Index> nameToIndexes;
+
+ private IndexQueryFactory<IndexQuery> indexQueryFactory;
+
/**
* The ExtensibleMatchingRuleIndex instance for ExtensibleMatchingRule
* indexes.
@@ -131,6 +138,7 @@
/**
* 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.
@@ -139,71 +147,73 @@
* @throws ConfigException if a configuration related error occurs.
*/
public AttributeIndex(LocalDBIndexCfg indexConfig, State state,
- Environment env,
- EntryContainer entryContainer)
+ Environment env, EntryContainer entryContainer)
throws DatabaseException, 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();
+ String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
final JEIndexConfig config = new JEIndexConfig(indexConfig.getSubstringLength());
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.EQUALITY))
+ if (indexConfig.getIndexType().contains(IndexType.EQUALITY))
{
this.equalityIndex = buildExtIndex(
name, attrType, attrType.getEqualityMatchingRule(), new EqualityIndexer(attrType));
+ nameToIndexes.put(IndexType.EQUALITY.toString(), equalityIndex);
}
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.PRESENCE))
+ if (indexConfig.getIndexType().contains(IndexType.PRESENCE))
{
this.presenceIndex = newIndex(name + ".presence",
new PresenceIndexer(attrType), indexConfig.getIndexEntryLimit());
+ nameToIndexes.put(IndexType.PRESENCE.toString(), presenceIndex);
}
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.SUBSTRING))
+ if (indexConfig.getIndexType().contains(IndexType.SUBSTRING))
{
this.substringIndex = buildExtIndex(
name, attrType, attrType.getSubstringMatchingRule(), new SubstringIndexer(attrType, config));
+ //nameToIndexes.put(IndexType.SUBSTRING.toString(), substringIndex);
}
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.ORDERING))
+ if (indexConfig.getIndexType().contains(IndexType.ORDERING))
{
this.orderingIndex = buildExtIndex(
name, attrType, attrType.getOrderingMatchingRule(), new OrderingIndexer(attrType));
+ nameToIndexes.put(IndexType.ORDERING.toString(), orderingIndex);
}
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.APPROXIMATE))
+
+ if (indexConfig.getIndexType().contains(IndexType.APPROXIMATE))
{
this.approximateIndex = buildExtIndex(
name, attrType, attrType.getApproximateMatchingRule(), new ApproximateIndexer(attrType));
+ nameToIndexes.put(IndexType.APPROXIMATE.toString(), approximateIndex);
}
- if (indexConfig.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
+
+ indexQueryFactory = new IndexQueryFactoryImpl(nameToIndexes, config);
+
+ if (indexConfig.getIndexType().contains(IndexType.EXTENSIBLE))
{
- Set<String> extensibleRules =
- indexConfig.getIndexExtensibleMatchingRule();
+ Set<String> extensibleRules = indexConfig.getIndexExtensibleMatchingRule();
if(extensibleRules == null || extensibleRules.isEmpty())
{
throw new ConfigException(ERR_CONFIG_INDEX_TYPE_NEEDS_MATCHING_RULE.get(attrType, "extensible"));
}
extensibleIndexes = new ExtensibleMatchingRuleIndex();
- //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.
+
+ // 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(String ruleName:extensibleRules)
{
- ExtensibleMatchingRule rule =
- DirectoryServer.getExtensibleMatchingRule(toLowerCase(ruleName));
+ ExtensibleMatchingRule rule = DirectoryServer.getExtensibleMatchingRule(toLowerCase(ruleName));
if(rule == null)
{
logger.error(ERR_CONFIG_INDEX_TYPE_NEEDS_VALID_MATCHING_RULE, attrType, ruleName);
@@ -221,11 +231,9 @@
extensibleIndexes.addIndex(extIndex, indexID);
}
extensibleIndexes.addRule(indexID, rule);
- indexMap.put(indexer.getExtensibleIndexID(),
- extensibleIndexes.getIndex(indexID));
+ indexMap.put(indexer.getExtensibleIndexID(), extensibleIndexes.getIndex(indexID));
}
- IndexQueryFactory<IndexQuery> factory =
- new IndexQueryFactoryImpl(indexMap, config);
+ IndexQueryFactory<IndexQuery> factory = new IndexQueryFactoryImpl(indexMap, config);
extensibleIndexes.addQueryFactory(rule, factory);
}
}
@@ -637,127 +645,47 @@
}
/**
- * Retrieve the entry IDs that might contain a given substring.
- * @param bytes A normalized substring of an attribute value.
- * @return The candidate entry IDs.
+ * Retrieve the entry IDs that might match the provided assertion.
+ *
+ * @param indexQuery
+ * The query used to retrieve entries.
+ * @param indexName
+ * The name of index used to retrieve entries.
+ * @param filter
+ * The filter on entries.
+ * @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.
*/
- private EntryIDSet matchSubstring(byte[] bytes)
- { // FIXME replace this code with SDK's
- // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.createIndexQuery()
+ private EntryIDSet evaluateIndexQuery(IndexQuery indexQuery, String indexName, SearchFilter filter,
+ StringBuilder debugBuffer, DatabaseEnvironmentMonitor monitor)
+ {
+ LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
+ EntryIDSet results = indexQuery.evaluate(debugMessage);
- int substrLength = indexConfig.getSubstringLength();
-
- // There are two cases, depending on whether the user-provided
- // substring is smaller than the configured index substring length or not.
- if (bytes.length < substrLength)
+ if (debugBuffer != null)
{
- // Iterate through all the keys that have this value as the prefix.
-
- // Set the lower bound for a range search.
- byte[] lower = makeSubstringKey(bytes, 0, bytes.length);
-
- // Set the upper bound for a range search.
- // We need a key for the upper bound that is of equal length
- // but slightly greater than the lower bound.
- byte[] upper = makeSubstringKey(bytes, 0, bytes.length);
- for (int i = upper.length-1; i >= 0; i--)
- {
- if (upper[i] == 0xFF)
- {
- // We have to carry the overflow to the more significant byte.
- upper[i] = 0;
- }
- else
- {
- // No overflow, we can stop.
- upper[i] = (byte) (upper[i] + 1);
- break;
- }
- }
-
- // Read the range: lower <= keys < upper.
- return substringIndex.readRange(lower, upper, true, false);
+ debugBuffer.append("[INDEX:").append(indexConfig.getAttribute().getNameOrOID())
+ .append(".").append(indexName).append("]");
}
- else
+
+ if (monitor.isFilterUseEnabled())
{
- // Break the value up into fragments of length equal to the
- // index substring length, and read those keys.
-
- // Eliminate duplicates by putting the keys into a set.
- Set<byte[]> set =
- new TreeSet<byte[]>(substringIndex.indexer.getComparator());
-
- // Example: The value is ABCDE and the substring length is 3.
- // We produce the keys ABC BCD CDE.
- for (int first = 0, last = substrLength;
- last <= bytes.length; first++, last++)
+ if (results.isDefined())
{
- set.add(makeSubstringKey(bytes, first, substrLength));
- }
-
- EntryIDSet results = new EntryIDSet();
- DatabaseEntry key = new DatabaseEntry();
- for (byte[] keyBytes : set)
- {
- // Read the key.
- key.setData(keyBytes);
- EntryIDSet list = substringIndex.readKey(key, null, LockMode.DEFAULT);
-
- // Incorporate them into the results.
- results.retainAll(list);
-
- // We may have reached the point of diminishing returns where
- // it is quicker to stop now and process the current small number of
- // candidates.
- if (results.isDefined() &&
- results.size() <= IndexFilter.FILTER_CANDIDATE_THRESHOLD)
- {
- break;
- }
- }
-
- return results;
- }
- }
-
- /**
- * Uses an equality index to retrieve the entry IDs that might contain a
- * given initial substring.
- * @param bytes A normalized initial substring of an attribute value.
- * @return The candidate entry IDs.
- */
- private EntryIDSet matchInitialSubstring(byte[] bytes)
- { // FIXME replace this code with SDK's
- // AbstractSubstringMatchingRuleImpl.DefaultSubstringAssertion.createIndexQuery()
-
- // Iterate through all the keys that have this value as the prefix.
-
- // Set the lower bound for a range search.
- byte[] lower = bytes;
-
- // Set the upper bound for a range search.
- // We need a key for the upper bound that is of equal length
- // but slightly greater than the lower bound.
- byte[] upper = new byte[bytes.length];
- System.arraycopy(bytes,0, upper, 0, bytes.length);
-
- for (int i = upper.length-1; i >= 0; i--)
- {
- if (upper[i] == 0xFF)
- {
- // We have to carry the overflow to the more significant byte.
- upper[i] = 0;
+ monitor.updateStats(filter, results.size());
}
else
{
- // No overflow, we can stop.
- upper[i] = (byte) (upper[i] + 1);
- break;
+ monitor.updateStats(filter, debugMessage.toMessage());
}
}
-
- // Read the range: lower <= keys < upper.
- return equalityIndex.readRange(lower, upper, true, false);
+ return results;
}
/**
@@ -776,62 +704,11 @@
StringBuilder debugBuffer,
DatabaseEnvironmentMonitor monitor)
{
- if (equalityIndex == null)
- {
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(equalityFilter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("equality",
- indexConfig.getAttribute().getNameOrOID()));
- }
- return new EntryIDSet();
- }
-
- try
- {
- // Make a key from the normalized assertion value.
- MatchingRule equalityRule = equalityFilter.getAttributeType().
- getEqualityMatchingRule();
- byte[] keyBytes = equalityRule.normalizeAssertionValue(
- equalityFilter.getAssertionValue()).toByteArray();
- DatabaseEntry key = new DatabaseEntry(keyBytes);
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("equality]");
- }
-
- // Read the key.
- EntryIDSet idSet = equalityIndex.readKey(key, null, LockMode.DEFAULT);
- if(monitor.isFilterUseEnabled())
- {
- if(idSet.isDefined())
- {
- monitor.updateStats(equalityFilter, idSet.size());
- }
- else if(!equalityIndex.isTrusted())
- {
- monitor.updateStats(equalityFilter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- equalityIndex.getName()));
- }
- else if(equalityIndex.isRebuildRunning())
- {
- monitor.updateStats(equalityFilter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- equalityIndex.getName()));
- }
- else
- {
- monitor.updateStats(equalityFilter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- equalityIndex.getName()));
- }
- }
- return idSet;
+ 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)
{
@@ -856,54 +733,8 @@
StringBuilder debugBuffer,
DatabaseEnvironmentMonitor monitor)
{
- if (presenceIndex == null)
- {
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("presence",
- indexConfig.getAttribute().getNameOrOID()));
- }
- return new EntryIDSet();
- }
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("presence]");
- }
-
- // Read the presence key
- EntryIDSet idSet =
- presenceIndex.readKey(presenceKey, null, LockMode.DEFAULT);
- if(monitor.isFilterUseEnabled())
- {
- if(idSet.isDefined())
- {
- monitor.updateStats(filter, idSet.size());
- }
- else if(!presenceIndex.isTrusted())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- presenceIndex.getName()));
- }
- else if(presenceIndex.isRebuildRunning())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- presenceIndex.getName()));
- }
- else
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- presenceIndex.getName()));
- }
- }
- return idSet;
+ final IndexQuery indexQuery = indexQueryFactory.createMatchAllQuery();
+ return evaluateIndexQuery(indexQuery, "presence", filter, debugBuffer, monitor);
}
/**
@@ -938,88 +769,22 @@
* @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)
+ public EntryIDSet evaluateLessOrEqualFilter(SearchFilter filter, StringBuilder debugBuffer,
+ DatabaseEnvironmentMonitor monitor)
{
return evaluateOrderingFilter(filter, false, debugBuffer, monitor);
}
- private EntryIDSet evaluateOrderingFilter(SearchFilter filter,
- boolean greater, StringBuilder debugBuffer,
+ private EntryIDSet evaluateOrderingFilter(SearchFilter filter, boolean greater, StringBuilder debugBuffer,
DatabaseEnvironmentMonitor monitor)
{
-
- if (orderingIndex == null)
- {
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("ordering",
- indexConfig.getAttribute().getNameOrOID()));
- }
- return new EntryIDSet();
- }
-
- try
- {
- // Use the ordering matching rule to normalize the value.
- MatchingRule orderingRule = filter.getAttributeType().getOrderingMatchingRule();
- byte[] normalizedValue = orderingRule.normalizeAssertionValue(
- filter.getAssertionValue()).toByteArray();
-
- // Set the lower and upper bounds for a range search.
- byte[] lower;
- byte[] upper;
- if (greater)
- {
- // Set upper bound to 0 to search all keys greater than the lower bound.
- lower = normalizedValue;
- upper = new byte[0];
- }
- else
- {
- // Set lower bound to 0 to start the range search from the smallest key.
- lower = new byte[0];
- upper = normalizedValue;
- }
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("ordering]");
- }
-
- // Read the range: lower <= keys < upper OR lower < keys <= upper
- EntryIDSet idSet = orderingIndex.readRange(lower, upper, greater, !greater);
- if(monitor.isFilterUseEnabled())
- {
- if(idSet.isDefined())
- {
- monitor.updateStats(filter, idSet.size());
- }
- else if(!orderingIndex.isTrusted())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- orderingIndex.getName()));
- }
- else if(orderingIndex.isRebuildRunning())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- orderingIndex.getName()));
- }
- else
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- orderingIndex.getName()));
- }
- }
- return idSet;
+ 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)
{
@@ -1044,165 +809,12 @@
StringBuilder debugBuffer,
DatabaseEnvironmentMonitor monitor)
{
- SubstringMatchingRule matchRule =
- filter.getAttributeType().getSubstringMatchingRule();
-
- try
- {
- ArrayList<ByteString> elements = new ArrayList<ByteString>();
- EntryIDSet results = new EntryIDSet();
-
- if (filter.getSubInitialElement() != null)
- {
- // Use the equality index for initial substrings if possible.
- if (equalityIndex != null && matchRule != null)
- {
- ByteString normValue =
- matchRule.normalizeSubstring(filter.getSubInitialElement());
- byte[] normBytes = normValue.toByteArray();
-
- EntryIDSet list = matchInitialSubstring(normBytes);
- results.retainAll(list);
-
- if (results.isDefined() &&
- results.size() <= IndexFilter.FILTER_CANDIDATE_THRESHOLD)
- {
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().
- getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("equality]");
- }
-
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(filter, results.size());
- }
- return results;
- }
- }
- else
- {
- elements.add(filter.getSubInitialElement());
- }
- }
-
- if (substringIndex == null)
- {
- if(monitor.isFilterUseEnabled())
- {
- if(!results.isDefined())
- {
- if(filter.getSubInitialElement() != null)
- {
- if(equalityIndex == null)
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("equality",
- indexConfig.getAttribute().getNameOrOID()));
- }
- else if(!equalityIndex.isTrusted())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- equalityIndex.getName()));
- }
- else if(equalityIndex.isRebuildRunning())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- equalityIndex.getName()));
- }
- else
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- equalityIndex.getName()));
- }
- }
- else
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("substring",
- indexConfig.getAttribute().getNameOrOID()));
- }
- }
- else
- {
- monitor.updateStats(filter, results.size());
- }
- }
- return results;
- }
-
- // We do not distinguish between sub and final elements
- // in the substring index. Put all the elements into a single list.
- elements.addAll(filter.getSubAnyElements());
- if (filter.getSubFinalElement() != null)
- {
- elements.add(filter.getSubFinalElement());
- }
-
- // Iterate through each substring element.
- for (ByteString element : elements)
- {
- // Normalize the substring according to the substring matching rule.
- ByteString normValue = matchRule.normalizeSubstring(element);
- byte[] normBytes = normValue.toByteArray();
-
- // Get the candidate entry IDs from the index.
- EntryIDSet list = matchSubstring(normBytes);
-
- // Incorporate them into the results.
- results.retainAll(list);
-
- // We may have reached the point of diminishing returns where
- // it is quicker to stop now and process the current small number of
- // candidates.
- if (results.isDefined() &&
- results.size() <= IndexFilter.FILTER_CANDIDATE_THRESHOLD)
- {
- break;
- }
- }
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("substring]");
- }
-
- if(monitor.isFilterUseEnabled())
- {
- if(results.isDefined())
- {
- monitor.updateStats(filter, results.size());
- }
- else if(!substringIndex.isTrusted())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- substringIndex.getName()));
- }
- else if(substringIndex.isRebuildRunning())
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- substringIndex.getName()));
- }
- else
- {
- monitor.updateStats(filter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- substringIndex.getName()));
- }
- }
-
- return results;
+ 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)
{
@@ -1212,36 +824,41 @@
}
/**
- * Retrieve the entry IDs that might have a value greater than or
- * equal to the lower bound value, and less than or equal to the
- * upper bound value.
+ * Retrieve the entry IDs that might match two filters that restrict a value
+ * to both a lower bound and an upper bound.
*
- * @param lowerValue The lower bound assertion value
- * @param upperValue The upper bound assertion value
- * @return The candidate entry IDs.
+ * @param filter1
+ * The first filter, that is either a less-or-equal filter or a
+ * greater-or-equal filter.
+ * @param filter2
+ * The second filter, that is either a less-or-equal filter or a
+ * greater-or-equal filter. It must not be of the same type than the
+ * first 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 match both filters.
*/
- public EntryIDSet evaluateBoundedRange(ByteString lowerValue, ByteString upperValue)
+ public EntryIDSet evaluateBoundedRange(SearchFilter filter1, SearchFilter filter2, StringBuilder debugBuffer,
+ DatabaseEnvironmentMonitor monitor)
{
- if (orderingIndex == null)
- {
- return new EntryIDSet();
- }
-
- try
- {
- // Set the lower and upper bounds for a range search.
- MatchingRule orderingRule = getAttributeType().getOrderingMatchingRule();
- byte[] lower = orderingRule.normalizeAssertionValue(lowerValue).toByteArray();
- byte[] upper = orderingRule.normalizeAssertionValue(upperValue).toByteArray();
-
- // Read the range: lower <= keys <= upper.
- return orderingIndex.readRange(lower, upper, true, true);
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return new EntryIDSet();
- }
+ // 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
+ // 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);
+ results.retainAll(results2);
+ return results;
}
/**
@@ -1356,66 +973,14 @@
* @return The candidate entry IDs that might contain the filter
* assertion value.
*/
- public EntryIDSet evaluateApproximateFilter(SearchFilter approximateFilter,
- StringBuilder debugBuffer,
- DatabaseEnvironmentMonitor monitor)
+ public EntryIDSet evaluateApproximateFilter(SearchFilter approximateFilter, StringBuilder debugBuffer,
+ DatabaseEnvironmentMonitor monitor)
{
- if (approximateIndex == null)
- {
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(approximateFilter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("approximate",
- indexConfig.getAttribute().getNameOrOID()));
- }
- return new EntryIDSet();
- }
-
- try
- {
- MatchingRule approximateMatchingRule =
- approximateFilter.getAttributeType().getApproximateMatchingRule();
- // Make a key from the normalized assertion value.
- byte[] keyBytes = approximateMatchingRule.normalizeAssertionValue(
- approximateFilter.getAssertionValue()).toByteArray();
- DatabaseEntry key = new DatabaseEntry(keyBytes);
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("approximate]");
- }
-
- // Read the key.
- EntryIDSet idSet = approximateIndex.readKey(key, null, LockMode.DEFAULT);
- if(monitor.isFilterUseEnabled())
- {
- if(idSet.isDefined())
- {
- monitor.updateStats(approximateFilter, idSet.size());
- }
- else if(!approximateIndex.isTrusted())
- {
- monitor.updateStats(approximateFilter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- approximateIndex.getName()));
- }
- else if(approximateIndex.isRebuildRunning())
- {
- monitor.updateStats(approximateFilter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- approximateIndex.getName()));
- }
- else
- {
- monitor.updateStats(approximateFilter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- approximateIndex.getName()));
- }
- }
- return idSet;
+ try {
+ MatchingRule matchRule = approximateFilter.getAttributeType().getApproximateMatchingRule();
+ IndexQuery indexQuery = matchRule.getAssertion(approximateFilter.getAssertionValue())
+ .createIndexQuery(indexQueryFactory);
+ return evaluateIndexQuery(indexQuery, "approximate", approximateFilter, debugBuffer, monitor);
}
catch (DecodeException e)
{
@@ -1609,8 +1174,7 @@
try
{
AttributeType attrType = cfg.getAttribute();
- String name =
- entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
+ String name = entryContainer.getDatabasePrefix() + "_" + attrType.getNameOrOID();
final int indexEntryLimit = cfg.getIndexEntryLimit();
final JEIndexConfig config = new JEIndexConfig(cfg.getSubstringLength());
@@ -1620,6 +1184,7 @@
{
equalityIndex = openNewIndex(name, attrType,
new EqualityIndexer(attrType), adminActionRequired, messages);
+ nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString(), equalityIndex);
}
else
{
@@ -1627,8 +1192,7 @@
if(this.equalityIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(equalityIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(equalityIndex.getName()));
this.equalityIndex.setIndexEntryLimit(indexEntryLimit);
}
}
@@ -1640,6 +1204,7 @@
entryContainer.exclusiveLock.lock();
try
{
+ nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.EQUALITY.toString());
entryContainer.deleteDatabase(equalityIndex);
equalityIndex = null;
}
@@ -1657,6 +1222,7 @@
Indexer presenceIndexer = new PresenceIndexer(attrType);
presenceIndex = newIndex(name + ".presence", presenceIndexer, indexEntryLimit);
openIndex(presenceIndex, adminActionRequired, messages);
+ nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString(), presenceIndex);
}
else
{
@@ -1664,8 +1230,7 @@
if(this.presenceIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(presenceIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(presenceIndex.getName()));
}
}
}
@@ -1676,6 +1241,7 @@
entryContainer.exclusiveLock.lock();
try
{
+ nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.PRESENCE.toString());
entryContainer.deleteDatabase(presenceIndex);
presenceIndex = null;
}
@@ -1695,6 +1261,7 @@
Index index = newIndex(name + "." + indexer.getExtensibleIndexID(),
extIndexer, indexEntryLimit);
substringIndex = openIndex(index, adminActionRequired, messages);
+ nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString(), substringIndex);
}
else
{
@@ -1702,8 +1269,7 @@
if(this.substringIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(substringIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(substringIndex.getName()));
}
if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
@@ -1719,6 +1285,7 @@
entryContainer.exclusiveLock.lock();
try
{
+ nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.SUBSTRING.toString());
entryContainer.deleteDatabase(substringIndex);
substringIndex = null;
}
@@ -1735,6 +1302,7 @@
{
orderingIndex = openNewIndex(name, attrType,
new OrderingIndexer(attrType), adminActionRequired, messages);
+ nameToIndexes.put(LocalDBIndexCfgDefn.IndexType.ORDERING.toString(), orderingIndex);
}
else
{
@@ -1742,8 +1310,7 @@
if(this.orderingIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(orderingIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(orderingIndex.getName()));
}
}
}
@@ -1754,6 +1321,7 @@
entryContainer.exclusiveLock.lock();
try
{
+ nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.ORDERING.toString());
entryContainer.deleteDatabase(orderingIndex);
orderingIndex = null;
}
@@ -1764,13 +1332,13 @@
}
}
- if (cfg.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.APPROXIMATE))
+ 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
{
@@ -1778,8 +1346,7 @@
if(this.approximateIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(approximateIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(approximateIndex.getName()));
}
}
}
@@ -1790,6 +1357,7 @@
entryContainer.exclusiveLock.lock();
try
{
+ nameToIndexes.remove(LocalDBIndexCfgDefn.IndexType.APPROXIMATE.toString());
entryContainer.deleteDatabase(approximateIndex);
approximateIndex = null;
}
@@ -1800,22 +1368,18 @@
}
}
- if (cfg.getIndexType().contains(
- LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
+ if (cfg.getIndexType().contains(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE))
{
- Set<String> extensibleRules =
- cfg.getIndexExtensibleMatchingRule();
- Set<ExtensibleMatchingRule> validRules =
- new HashSet<ExtensibleMatchingRule>();
+ Set<String> extensibleRules = cfg.getIndexExtensibleMatchingRule();
+ Set<ExtensibleMatchingRule> validRules = new HashSet<ExtensibleMatchingRule>();
if(extensibleIndexes == null)
{
extensibleIndexes = new ExtensibleMatchingRuleIndex();
}
for(String ruleName:extensibleRules)
{
- ExtensibleMatchingRule rule =
- DirectoryServer.getExtensibleMatchingRule(toLowerCase(ruleName));
- if(rule == null)
+ ExtensibleMatchingRule rule = DirectoryServer.getExtensibleMatchingRule(toLowerCase(ruleName));
+ if(rule == null)
{
logger.error(ERR_CONFIG_INDEX_TYPE_NEEDS_VALID_MATCHING_RULE, attrType, ruleName);
continue;
@@ -1838,8 +1402,7 @@
if(extensibleIndex.setIndexEntryLimit(indexEntryLimit))
{
adminActionRequired.set(true);
- messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD
- .get(extensibleIndex.getName()));
+ messages.add(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(extensibleIndex.getName()));
}
if (indexConfig.getSubstringLength() != cfg.getSubstringLength())
{
@@ -1850,8 +1413,7 @@
extensibleIndexes.addRule(indexID, rule);
indexMap.put(indexer.getExtensibleIndexID(), extensibleIndexes.getIndex(indexID));
}
- final IndexQueryFactory<IndexQuery> factory =
- new IndexQueryFactoryImpl(indexMap, config);
+ IndexQueryFactory<IndexQuery> factory = new IndexQueryFactoryImpl(indexMap, config);
extensibleIndexes.addQueryFactory(rule, factory);
}
//Some rules might have been removed from the configuration.
@@ -1928,8 +1490,7 @@
indexConfig = cfg;
- return new ConfigChangeResult(
- ResultCode.SUCCESS, adminActionRequired.get(), messages);
+ return new ConfigChangeResult(ResultCode.SUCCESS, adminActionRequired.get(), messages);
}
catch(Exception e)
{
@@ -2168,101 +1729,37 @@
DatabaseEnvironmentMonitor monitor)
{
//Get the Matching Rule OID of the filter.
- String nOID = extensibleFilter.getMatchingRuleID();
+ String matchRuleOID = extensibleFilter.getMatchingRuleID();
/**
* Use the default equality index in two conditions:
* 1. There is no matching rule provided
* 2. The matching rule specified is actually the default equality.
*/
- MatchingRule eqRule =
- indexConfig.getAttribute().getEqualityMatchingRule();
- if (nOID == null
- || nOID.equals(eqRule.getOID())
- || nOID.equalsIgnoreCase(eqRule.getNameOrOID()))
+ MatchingRule eqRule = indexConfig.getAttribute().getEqualityMatchingRule();
+ if (matchRuleOID == null
+ || matchRuleOID.equals(eqRule.getOID())
+ || matchRuleOID.equalsIgnoreCase(eqRule.getNameOrOID()))
{
//No matching rule is defined; use the default equality matching rule.
- if(equalityIndex == null)
- {
- // There is no index on this matching rule.
- if(monitor.isFilterUseEnabled())
- {
- monitor.updateStats(extensibleFilter,
- INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get("equality",
- indexConfig.getAttribute().getNameOrOID()));
- }
- return IndexQuery.createNullIndexQuery().evaluate(null);
- }
- try
- {
- // Make a key from the normalized assertion value.
- MatchingRule rule =
- extensibleFilter.getAttributeType().getEqualityMatchingRule();
- ByteString value = extensibleFilter.getAssertionValue();
- byte[] keyBytes = rule.normalizeAssertionValue(value).toByteArray();
- DatabaseEntry key = new DatabaseEntry(keyBytes);
-
- if(debugBuffer != null)
- {
- debugBuffer.append("[INDEX:");
- debugBuffer.append(indexConfig.getAttribute().getNameOrOID());
- debugBuffer.append(".");
- debugBuffer.append("equality]");
- }
-
- // Read the key.
- EntryIDSet idSet = equalityIndex.readKey(key, null, LockMode.DEFAULT);
- if(monitor.isFilterUseEnabled())
- {
- if(idSet.isDefined())
- {
- monitor.updateStats(extensibleFilter, idSet.size());
- }
- else if(!equalityIndex.isTrusted())
- {
- monitor.updateStats(extensibleFilter,
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- equalityIndex.getName()));
- }
- else if(equalityIndex.isRebuildRunning())
- {
- monitor.updateStats(extensibleFilter,
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- equalityIndex.getName()));
- }
- else
- {
- monitor.updateStats(extensibleFilter,
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- equalityIndex.getName()));
- }
- }
- return idSet;
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
- return IndexQuery.createNullIndexQuery().evaluate(null);
- }
+ return evaluateEqualityFilter(extensibleFilter, debugBuffer, monitor);
}
- ExtensibleMatchingRule rule =
- DirectoryServer.getExtensibleMatchingRule(nOID);
+
+ ExtensibleMatchingRule rule = DirectoryServer.getExtensibleMatchingRule(matchRuleOID);
IndexQueryFactory<IndexQuery> factory = null;
- if(extensibleIndexes == null
- || (factory = extensibleIndexes.getQueryFactory(rule))==null)
+ if (extensibleIndexes == null || (factory = extensibleIndexes.getQueryFactory(rule)) == null)
{
// There is no index on this matching rule.
- if(monitor.isFilterUseEnabled())
+ if (monitor.isFilterUseEnabled())
{
- monitor.updateStats(extensibleFilter,
- INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(nOID,
- indexConfig.getAttribute().getNameOrOID()));
+ monitor.updateStats(extensibleFilter, INFO_JEB_INDEX_FILTER_MATCHING_RULE_NOT_INDEXED.get(
+ matchRuleOID, indexConfig.getAttribute().getNameOrOID()));
}
return IndexQuery.createNullIndexQuery().evaluate(null);
}
try
{
- if(debugBuffer != null)
+ if (debugBuffer != null)
{
debugBuffer.append("[INDEX:");
for (ExtensibleIndexer indexer : rule.getIndexers())
@@ -2276,25 +1773,17 @@
}
ByteString assertionValue = extensibleFilter.getAssertionValue();
IndexQuery expression = rule.createIndexQuery(assertionValue, factory);
- List<LocalizableMessage> debugMessages =
- monitor.isFilterUseEnabled() ? new ArrayList<LocalizableMessage>() : null;
- EntryIDSet idSet = expression.evaluate(debugMessages);
- if(monitor.isFilterUseEnabled())
+ LocalizableMessageBuilder debugMessage = monitor.isFilterUseEnabled() ? new LocalizableMessageBuilder() : null;
+ EntryIDSet idSet = expression.evaluate(debugMessage);
+ if (monitor.isFilterUseEnabled())
{
- if(idSet.isDefined())
+ if (idSet.isDefined())
{
monitor.updateStats(extensibleFilter, idSet.size());
}
else
{
- if(debugMessages != null && !debugMessages.isEmpty())
- {
- monitor.updateStats(extensibleFilter, debugMessages.get(0));
- }
- else
- {
- monitor.updateStats(extensibleFilter, LocalizableMessage.EMPTY);
- }
+ monitor.updateStats(extensibleFilter, debugMessage.toMessage());
}
}
return idSet;
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexFilter.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexFilter.java
index 11485a3..dd3119d 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexFilter.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexFilter.java
@@ -22,7 +22,7 @@
*
*
* Copyright 2006-2010 Sun Microsystems, Inc.
- * Portions copyright 2011 ForgeRock AS
+ * Portions copyright 2011-2014 ForgeRock AS
*
*/
package org.opends.server.backends.jeb;
@@ -298,11 +298,10 @@
ArrayList<SearchFilter> rangeList = rangeEntry.getValue();
if (rangeList.size() == 2)
{
- SearchFilter a = rangeList.get(0);
- SearchFilter b = rangeList.get(1);
+ SearchFilter filter1 = rangeList.get(0);
+ SearchFilter filter2 = rangeList.get(1);
- AttributeIndex attributeIndex =
- entryContainer.getAttributeIndex(rangeEntry.getKey());
+ AttributeIndex attributeIndex = entryContainer.getAttributeIndex(rangeEntry.getKey());
if (attributeIndex == null)
{
if(monitor.isFilterUseEnabled())
@@ -313,104 +312,18 @@
}
continue;
}
+ EntryIDSet set = attributeIndex.evaluateBoundedRange(filter1, filter2, buffer, monitor);
- if (a.getFilterType() == FilterType.GREATER_OR_EQUAL &&
- b.getFilterType() == FilterType.LESS_OR_EQUAL)
+ if(monitor.isFilterUseEnabled() && set.isDefined())
{
- // Like (cn>=A)(cn<=B).
- EntryIDSet set;
- set = attributeIndex.evaluateBoundedRange(a.getAssertionValue(),
- b.getAssertionValue());
-
- if (buffer != null)
- {
- a.toString(buffer);
- b.toString(buffer);
- set.toString(buffer);
- }
-
- if(monitor.isFilterUseEnabled())
- {
- if(set.isDefined())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- set.size());
- }
- else if(!attributeIndex.orderingIndex.isTrusted())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- attributeIndex.orderingIndex.getName()));
- }
- else if(attributeIndex.orderingIndex.isRebuildRunning())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- attributeIndex.orderingIndex.getName()));
- }
- else
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- attributeIndex.orderingIndex.getName()));
- }
- }
-
- if (retainAll(results, set))
- {
- return results;
- }
- continue;
+ monitor.updateStats(SearchFilter.createANDFilter(rangeList), set.size());
}
- else if (a.getFilterType() == FilterType.LESS_OR_EQUAL &&
- b.getFilterType() == FilterType.GREATER_OR_EQUAL)
+
+ if (retainAll(results, set))
{
- // Like (cn<=A)(cn>=B).
- EntryIDSet set;
- set = attributeIndex.evaluateBoundedRange(b.getAssertionValue(),
- a.getAssertionValue());
-
- if (buffer != null)
- {
- a.toString(buffer);
- b.toString(buffer);
- set.toString(buffer);
- }
-
- if(monitor.isFilterUseEnabled())
- {
- if(set.isDefined())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- set.size());
- }
- else if(!attributeIndex.orderingIndex.isTrusted())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- attributeIndex.orderingIndex.getName()));
- }
- else if(attributeIndex.orderingIndex.isRebuildRunning())
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- attributeIndex.orderingIndex.getName()));
- }
- else
- {
- monitor.updateStats(SearchFilter.createANDFilter(rangeList),
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- attributeIndex.orderingIndex.getName()));
- }
- }
-
-
- if (retainAll(results, set))
- {
- return results;
- }
- continue;
+ return results;
}
+ continue;
}
// Add to the remaining range components to be processed.
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
index acd6c4b..c15aa73 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQuery.java
@@ -29,10 +29,9 @@
-import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
import java.util.Collection;
-import java.util.List;
import static org.opends.server.backends.jeb.IndexFilter.*;
@@ -51,12 +50,12 @@
/**
* Evaluates the index query and returns the EntryIDSet.
*
- * @param debugMessages If not null, diagnostic messages will be written
+ * @param debugMessage If not null, diagnostic message will be written
* which will help to determine why the returned
* EntryIDSet is not defined.
- * @return The EntryIDSet as a result of evaulation of this query.
+ * @return The EntryIDSet as a result of evaluation of this query.
*/
- public abstract EntryIDSet evaluate(List<LocalizableMessage> debugMessages);
+ public abstract EntryIDSet evaluate(LocalizableMessageBuilder debugMessage);
@@ -117,7 +116,7 @@
* @param debugMessages
*/
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
return new EntryIDSet();
}
@@ -154,18 +153,18 @@
* @param debugMessages
*/
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
EntryIDSet entryIDs = null;
for (IndexQuery query : subIndexQueries)
{
if (entryIDs == null)
{
- entryIDs = query.evaluate(debugMessages);
+ entryIDs = query.evaluate(debugMessage);
}
else
{
- entryIDs.retainAll(query.evaluate(debugMessages));
+ entryIDs.retainAll(query.evaluate(debugMessage));
}
if (entryIDs.isDefined()
&& entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
@@ -207,18 +206,18 @@
* @param debugMessages
*/
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
EntryIDSet entryIDs = null;
for (IndexQuery query : subIndexQueries)
{
if (entryIDs == null)
{
- entryIDs = query.evaluate(debugMessages);
+ entryIDs = query.evaluate(debugMessage);
}
else
{
- entryIDs.addAll(query.evaluate(debugMessages));
+ entryIDs.addAll(query.evaluate(debugMessage));
}
if (entryIDs.isDefined()
&& entryIDs.size() <= FILTER_CANDIDATE_THRESHOLD)
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
index ffcdca7..92386d9 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexQueryFactoryImpl.java
@@ -27,10 +27,9 @@
package org.opends.server.backends.jeb;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
-import org.forgerock.i18n.LocalizableMessage;
+import org.forgerock.i18n.LocalizableMessageBuilder;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
import org.forgerock.opendj.ldap.spi.IndexingOptions;
@@ -48,6 +47,8 @@
IndexQueryFactory<IndexQuery>
{
+ private static final String PRESENCE_INDEX_KEY = "presence";
+
/**
* The Map containing the string type identifier and the corresponding index.
*/
@@ -79,34 +80,35 @@
{
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
// Read the database and get Record for the key.
DatabaseEntry key = new DatabaseEntry(value.toByteArray());
// Select the right index to be used.
Index index = indexMap.get(indexID);
- EntryIDSet entrySet =
- index.readKey(key, null, LockMode.DEFAULT);
- if(debugMessages != null && !entrySet.isDefined())
+ if (index == null)
+ {
+ if(debugMessage != null)
+ {
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID, ""));
+ }
+ return createMatchAllQuery().evaluate(debugMessage);
+ }
+ EntryIDSet entrySet = index.readKey(key, null, LockMode.DEFAULT);
+ if(debugMessage != null && !entrySet.isDefined())
{
if(!index.isTrusted())
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
}
else if(index.isRebuildRunning())
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
}
else
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
}
}
return entrySet;
@@ -126,32 +128,33 @@
{
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
// Find the right index.
Index index = indexMap.get(indexID);
- EntryIDSet entrySet =
- index.readRange(lowerBound.toByteArray(), upperBound
- .toByteArray(), includeLowerBound, includeUpperBound);
- if(debugMessages != null && !entrySet.isDefined())
+ if (index == null)
+ {
+ if(debugMessage != null)
+ {
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(indexID, ""));
+ }
+ return createMatchAllQuery().evaluate(debugMessage);
+ }
+ EntryIDSet entrySet = index.readRange(lowerBound.toByteArray(), upperBound.toByteArray(),
+ includeLowerBound, includeUpperBound);
+ if(debugMessage != null && !entrySet.isDefined())
{
if(!index.isTrusted())
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_NOT_TRUSTED.get(index.getName()));
}
else if(index.isRebuildRunning())
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_REBUILD_IN_PROGRESS.get(index.getName()));
}
else
{
- debugMessages.add(
- INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(
- index.getName()));
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_LIMIT_EXCEEDED.get(index.getName()));
}
}
return entrySet;
@@ -191,11 +194,38 @@
{
return new IndexQuery()
{
-
@Override
- public EntryIDSet evaluate(List<LocalizableMessage> debugMessages)
+ public EntryIDSet evaluate(LocalizableMessageBuilder debugMessage)
{
- return new EntryIDSet();
+ Index index = indexMap.get(PRESENCE_INDEX_KEY);
+ if (index == null)
+ {
+ if(debugMessage != null)
+ {
+ debugMessage.append(INFO_JEB_INDEX_FILTER_INDEX_TYPE_DISABLED.get(index.getName(), ""));
+ }
+ 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()));
+ }
+ }
+
+ return entrySet;
}
};
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
index 7ff209b..df653d9 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/AbstractOrderingMatchingRule.java
@@ -28,8 +28,8 @@
import java.util.Comparator;
import org.forgerock.opendj.ldap.*;
+import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
import org.opends.server.api.AbstractMatchingRule;
-import org.opends.server.api.NotImplementedAssertion;
import org.opends.server.api.OrderingMatchingRule;
/**
@@ -57,46 +57,61 @@
/** {@inheritDoc} */
@Override
- public Assertion getAssertion(final ByteSequence value)
- throws DecodeException
+ public Assertion getAssertion(final ByteSequence assertionValue) throws DecodeException
{
- final ByteString assertionValue = normalizeAssertionValue(value);
- return new NotImplementedAssertion()
+ final ByteString normAssertionValue = normalizeAttributeValue(assertionValue);
+ return new Assertion()
{
@Override
- public ConditionResult matches(ByteSequence attributeValue)
+ public ConditionResult matches(final ByteSequence attributeValue)
{
- return ConditionResult.valueOf(compareValues(attributeValue, assertionValue) < 0);
+ return ConditionResult.valueOf(compareValues(attributeValue, normAssertionValue) < 0);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException
+ {
+ return factory.createRangeMatchQuery("ordering", ByteString.empty(), normAssertionValue, false, false);
}
};
}
/** {@inheritDoc} */
@Override
- public Assertion getGreaterOrEqualAssertion(ByteSequence value) throws DecodeException
+ public Assertion getGreaterOrEqualAssertion(final ByteSequence assertionValue) throws DecodeException
{
- final ByteString normAssertion = normalizeAssertionValue(value);
- return new NotImplementedAssertion()
+ final ByteString normAssertionValue = normalizeAttributeValue(assertionValue);
+ return new Assertion()
{
- @Override
- public ConditionResult matches(final ByteSequence normalizedAttributeValue)
- {
- return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertion) >= 0);
- }
+ @Override
+ public ConditionResult matches(final ByteSequence normalizedAttributeValue) {
+ return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertionValue) >= 0);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException {
+ return factory.createRangeMatchQuery("ordering", normAssertionValue, ByteString.empty(), true, false);
+ }
};
}
/** {@inheritDoc} */
@Override
- public Assertion getLessOrEqualAssertion(ByteSequence value) throws DecodeException
+ public Assertion getLessOrEqualAssertion(final ByteSequence assertionValue) throws DecodeException
{
- final ByteString normAssertion = normalizeAssertionValue(value);
- return new NotImplementedAssertion()
+ final ByteString normAssertionValue = normalizeAttributeValue(assertionValue);
+ return new Assertion()
{
@Override
public ConditionResult matches(final ByteSequence normalizedAttributeValue)
{
- return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertion) <= 0);
+ return ConditionResult.valueOf(compareValues(normalizedAttributeValue, normAssertionValue) <= 0);
+ }
+
+ @Override
+ public <T> T createIndexQuery(IndexQueryFactory<T> factory) throws DecodeException
+ {
+ return factory.createRangeMatchQuery("ordering", ByteString.empty(), normAssertionValue, false, true);
}
};
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CertificateExactMatchingRule.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CertificateExactMatchingRule.java
index a85513e..6d2b537 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CertificateExactMatchingRule.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/schema/CertificateExactMatchingRule.java
@@ -42,6 +42,7 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.ldap.Assertion;
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
@@ -369,5 +370,13 @@
return builder.toByteString();
}
+ /** {@inheritDoc} */
+ @Override
+ public Assertion getAssertion(ByteSequence assertionValue) throws DecodeException
+ {
+ final ByteString normAssertionValue = normalizeAssertionValue(assertionValue);
+ return getEqualityAssertion(normAssertionValue);
+ }
+
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/SearchFilter.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/SearchFilter.java
index c7c4f52..d6bcb26 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/SearchFilter.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/types/SearchFilter.java
@@ -42,7 +42,6 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ConditionResult;
-import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ResultCode;
import org.opends.server.api.MatchingRule;
import org.opends.server.api.SubstringMatchingRule;
@@ -2146,42 +2145,6 @@
return assertionValue;
}
- private ByteString getNormalizedAssertionValue() throws DecodeException
- {
- if (normalizedAssertionValue == null)
- {
- return normalizedAssertionValue = normalizeAssertionValue();
- }
- return normalizedAssertionValue;
- }
-
- private ByteString normalizeAssertionValue() throws DecodeException
- {
- switch (filterType)
- {
- case EQUALITY:
- return attributeType.getEqualityMatchingRule()
- .normalizeAssertionValue(assertionValue);
- case GREATER_OR_EQUAL:
- case LESS_OR_EQUAL:
- return attributeType.getOrderingMatchingRule()
- .normalizeAssertionValue(assertionValue);
- case APPROXIMATE_MATCH:
- return attributeType.getApproximateMatchingRule()
- .normalizeAssertionValue(assertionValue);
- case AND:
- case OR:
- case NOT:
- case PRESENT:
- case SUBSTRING:
- case EXTENSIBLE_MATCH:
- default:
- return null;
- }
- }
-
-
-
/**
* Retrieves the subInitial element for this substring filter.
*
@@ -3610,7 +3573,7 @@
case APPROXIMATE_MATCH:
return typeAndOptionsAndAssertionEqual(f);
case EXTENSIBLE_MATCH:
- return equalsExtensible(f);
+ return extensibleEqual(f);
default:
return false;
}
@@ -3641,23 +3604,15 @@
private boolean typeAndOptionsAndAssertionEqual(SearchFilter f)
{
- final boolean tmp =
- attributeType.equals(f.attributeType)
- && optionsEqual(attributeOptions, f.attributeOptions);
- try
- {
- return tmp && getNormalizedAssertionValue().equals(f.getNormalizedAssertionValue());
- }
- catch (DecodeException e)
- {
- return tmp && assertionValue.equals(f.assertionValue);
- }
+ return attributeType.equals(f.attributeType)
+ && optionsEqual(attributeOptions, f.attributeOptions)
+ && assertionValue.equals(f.assertionValue);
}
- private boolean substringEqual(SearchFilter f)
+ private boolean substringEqual(SearchFilter other)
{
- if (! attributeType.equals(f.attributeType))
+ if (! attributeType.equals(other.attributeType))
{
return false;
}
@@ -3667,20 +3622,43 @@
{
return false;
}
- try
- {
- Assertion thisAssertion = rule.getSubstringAssertion(subInitialElement, subAnyElements, subFinalElement);
- Assertion thatAssertion = rule.getSubstringAssertion(f.subInitialElement, f.subAnyElements, f.subFinalElement);
- return thisAssertion.equals(thatAssertion);
- }
- catch (DecodeException e)
+ if (! optionsEqual(attributeOptions, other.attributeOptions))
{
return false;
}
+
+ boolean initialCheck = subInitialElement == null ?
+ other.subInitialElement == null : subInitialElement.equals(other.subInitialElement);
+ if (!initialCheck)
+ {
+ return false;
+ }
+ boolean finalCheck = subFinalElement == null ?
+ other.subFinalElement == null : subFinalElement.equals(other.subFinalElement);
+ if (!finalCheck)
+ {
+ return false;
+ }
+ boolean anyCheck = subAnyElements == null ?
+ other.subAnyElements == null : subAnyElements.size() == other.subAnyElements.size();
+ if (!anyCheck)
+ {
+ return false;
+ }
+ if (subAnyElements != null)
+ {
+ for (int i = 0; i < subAnyElements.size(); i++)
+ {
+ if (! subAnyElements.get(i).equals(other.subAnyElements.get(i)))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
}
-
- private boolean equalsExtensible(SearchFilter f)
+ private boolean extensibleEqual(SearchFilter f)
{
if (attributeType == null)
{
@@ -3886,41 +3864,28 @@
private int typeAndAssertionHashCode()
{
- final int hashCode = attributeType.hashCode();
- try
- {
- return hashCode + getNormalizedAssertionValue().hashCode();
- }
- catch (DecodeException e)
- {
- return hashCode + assertionValue.hashCode();
- }
+ return attributeType.hashCode() + assertionValue.hashCode();
}
/** Returns hash code to use for substring filter. */
private int substringHashCode()
{
int hashCode = attributeType.hashCode();
- final MatchingRule rule = attributeType.getSubstringMatchingRule();
- if (rule != null)
+ if (subInitialElement != null)
{
- try
+ hashCode += subInitialElement.hashCode();
+ }
+ if (subAnyElements != null)
+ {
+ for (ByteString e : subAnyElements)
{
- return hashCode + rule.getSubstringAssertion(subInitialElement, subAnyElements, subFinalElement).hashCode();
- }
- catch (DecodeException e)
- {
- logger.traceException(e);
+ hashCode += e.hashCode();
}
}
-
- // Fallback to hash code based on elements
- hashCode += subInitialElement.hashCode();
- for (ByteString e : subAnyElements)
+ if (subFinalElement != null)
{
- hashCode += e.hashCode();
+ hashCode += subFinalElement.hashCode();
}
- hashCode += subFinalElement.hashCode();
return hashCode;
}
diff --git a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
index 47b5dbd..0a1b9a0 100644
--- a/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
+++ b/opendj-sdk/opendj3-server-dev/src/server/org/opends/server/workflowelement/externalchangelog/ECLSearchOperation.java
@@ -32,12 +32,10 @@
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.ByteString;
-import org.forgerock.opendj.ldap.DecodeException;
import org.forgerock.opendj.ldap.ModificationType;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.opends.server.api.ClientConnection;
-import org.opends.server.api.MatchingRule;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.config.ConfigConstants;
import org.opends.server.controls.*;
@@ -1247,17 +1245,7 @@
private static int extractChangeNumber(SearchFilter sf)
throws DirectoryException
{
- try
- {
- MatchingRule rule = sf.getAttributeType().getEqualityMatchingRule();
- ByteString normValue = rule.normalizeAssertionValue(sf.getAssertionValue());
- return Integer.decode(normValue.toString());
- }
- catch (DecodeException e)
- {
- throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, e
- .getMessageObject(), e);
- }
+ return Integer.decode(sf.getAssertionValue().toString());
}
private static boolean matches(SearchFilter sf, FilterType filterType,
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
index 3cff6ed..a4539be6 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -47,12 +47,6 @@
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;
@@ -647,15 +641,75 @@
@Test(dependsOnMethods = "testAdd")
public void testSearchIndex() throws Exception {
- InternalClientConnection conn =
- InternalClientConnection.getRootConnection();
+ InternalClientConnection conn = InternalClientConnection.getRootConnection();
Set<String> attribs = new LinkedHashSet<String>();
-
String debugString;
- int finalStartPos;
- int finalEndPos;
- int finalCount;
+ List<SearchResultEntry> result;
+ // search 1
+ result = doSubtreeSearch(conn, "(&(cn=Aaccf Amar)(cn=Ardyth Bainton))", attribs);
+ assertEquals(result.size(), 0);
+
+ // Adding a debug search attribute for next searches
+ attribs.add(ATTR_DEBUG_SEARCH_INDEX);
+
+ // search 2
+ result = doSubtreeSearch(conn, "(&(cn=Aaccf Amar)(employeeNumber=222))", attribs);
+
+ // Only one index should be used because it is below the FILTER_CANDIDATE
+ debugString = getDebugString(result);
+ assertTrue(debugString.split("cn").length <= 3);
+ assertResultsCountIs(1, debugString);
+
+ // search 3
+ result = doSubtreeSearch(conn, "(|(cn=Aaccf Amar)(cn=Ardyth Bainton))", attribs);
+
+ debugString = getDebugString(result);
+ assertFalse(debugString.contains("NOT-INDEXED"));
+ assertResultsCountIs(2, debugString);
+
+ // search 4
+ result = doSubtreeSearch(conn, "(&(employeeNumber=*)(cn=A*)(employeeNumber>=0)(employeeNumber<=z))", attribs);
+
+ debugString = getDebugString(result);
+ assertFalse(debugString.contains("NOT-INDEXED"));
+ assertResultsCountIs(12, debugString);
+
+ // search 5
+ result = doSubtreeSearch(conn,
+ "(&(employeeNumber<=z)(cn<=Abbey Abbie)(cn>=0)(|(cn>=Abahri Abazari)(employeeNumber<=9)))", attribs);
+
+
+ debugString = getDebugString(result);
+ assertFalse(debugString.contains("NOT-INDEXED"));
+ assertResultsCountIs(11, debugString);
+
+ // search 6
+ result = doSubtreeSearch(conn, "(cn~=Aartjan)", attribs);
+
+ debugString = getDebugString(result);
+ assertFalse(debugString.contains("NOT-INDEXED"));
+ assertResultsCountIs(1, debugString);
+ }
+
+ private void assertResultsCountIs(int expectedCount, String debugString)
+ {
+ int finalStartPos = debugString.indexOf("final=") + 13;
+ int finalEndPos = debugString.indexOf("]", finalStartPos);
+ int finalCount = Integer.valueOf(debugString.substring(finalStartPos, finalEndPos));
+ assertEquals(finalCount, expectedCount);
+ }
+
+ /** Returns the debug string from a search result. */
+ private String getDebugString(List<SearchResultEntry> result)
+ {
+ return result.get(0).getAttribute("debugsearchindex").get(0).toString();
+ }
+
+ /** Returns the results of subtree search on provided connection with provided filter. */
+ private List<SearchResultEntry> doSubtreeSearch(InternalClientConnection conn, String filter,
+ Set<String> attribs) throws Exception
+ {
InternalSearchOperation search =
conn.processSearch(DN.valueOf("dc=test,dc=com"),
SearchScope.WHOLE_SUBTREE,
@@ -663,111 +717,9 @@
0,
0,
false,
- LDAPFilter.decode("(&(cn=Aaccf Amar)(cn=Ardyth Bainton))").toSearchFilter(),
+ LDAPFilter.decode(filter).toSearchFilter(),
attribs);
-
- List<SearchResultEntry> result = search.getSearchEntries();
- assertEquals(result.size(), 0);
-
- attribs.add(ATTR_DEBUG_SEARCH_INDEX);
-
- search = conn.processSearch(DN.valueOf("dc=test,dc=com"),
- SearchScope.WHOLE_SUBTREE,
- DereferenceAliasesPolicy.NEVER,
- 0,
- 0,
- false,
- LDAPFilter.decode("(&(cn=Aaccf Amar)(employeeNumber=222))").toSearchFilter(),
- attribs);
-
- result = search.getSearchEntries();
-
- //Only one index should be used because it is below the FILTER_CANDIDATEassertEquals(ec.getDN2URI().)_THRESHOLD.
- debugString =
- result.get(0).getAttribute("debugsearchindex").get(0).toString();
- assertTrue(debugString.split("cn").length <= 3);
- finalStartPos = debugString.indexOf("final=") + 13;
- finalEndPos = debugString.indexOf("]", finalStartPos);
- finalCount = Integer.valueOf(debugString.substring(finalStartPos,
- finalEndPos));
- assertEquals(finalCount, 1);
-
- search = conn.processSearch(DN.valueOf("dc=test,dc=com"),
- SearchScope.WHOLE_SUBTREE,
- DereferenceAliasesPolicy.NEVER,
- 0,
- 0,
- false,
- LDAPFilter.decode("(|(cn=Aaccf Amar)(cn=Ardyth Bainton))").toSearchFilter(),
- attribs);
-
- result = search.getSearchEntries();
-
- debugString =
- result.get(0).getAttribute("debugsearchindex").get(0).toString();
- assertTrue(!debugString.contains("NOT-INDEXED"));
- finalStartPos = debugString.indexOf("final=") + 13;
- finalEndPos = debugString.indexOf("]", finalStartPos);
- finalCount = Integer.valueOf(debugString.substring(finalStartPos,
- finalEndPos));
- assertEquals(finalCount, 2);
-
- search = conn.processSearch(DN.valueOf("dc=test,dc=com"),
- SearchScope.WHOLE_SUBTREE,
- DereferenceAliasesPolicy.NEVER,
- 0,
- 0,
- false,
- LDAPFilter.decode("(&(employeeNumber=*)(cn=A*)(employeeNumber>=0)(employeeNumber<=z))").toSearchFilter(),
- attribs);
- result = search.getSearchEntries();
-
- debugString =
- result.get(0).getAttribute("debugsearchindex").get(0).toString();
- assertTrue(!debugString.contains("NOT-INDEXED"));
- finalStartPos = debugString.indexOf("final=") + 13;
- finalEndPos = debugString.indexOf("]", finalStartPos);
- finalCount = Integer.valueOf(debugString.substring(finalStartPos,
- finalEndPos));
- assertEquals(finalCount, 12);
-
- search = conn.processSearch(DN.valueOf("dc=test,dc=com"),
- SearchScope.WHOLE_SUBTREE,
- DereferenceAliasesPolicy.NEVER,
- 0,
- 0,
- false,
- LDAPFilter.decode("(&(employeeNumber<=z)(cn<=Abbey Abbie)(cn>=0)(|(cn>=Abahri Abazari)(employeeNumber<=9)))").toSearchFilter(),
- attribs);
- result = search.getSearchEntries();
-
- debugString =
- result.get(0).getAttribute("debugsearchindex").get(0).toString();
- assertTrue(!debugString.contains("NOT-INDEXED"));
- finalStartPos = debugString.indexOf("final=") + 13;
- finalEndPos = debugString.indexOf("]", finalStartPos);
- finalCount = Integer.valueOf(debugString.substring(finalStartPos,
- finalEndPos));
- assertEquals(finalCount, 11);
-
- search = conn.processSearch(DN.valueOf("dc=test,dc=com"),
- SearchScope.WHOLE_SUBTREE,
- DereferenceAliasesPolicy.NEVER,
- 0,
- 0,
- false,
- LDAPFilter.decode("(cn~=Aartjan)").toSearchFilter(),
- attribs);
- result = search.getSearchEntries();
-
- debugString =
- result.get(0).getAttribute("debugsearchindex").get(0).toString();
- assertTrue(!debugString.contains("NOT-INDEXED"));
- finalStartPos = debugString.indexOf("final=") + 13;
- finalEndPos = debugString.indexOf("]", finalStartPos);
- finalCount = Integer.valueOf(debugString.substring(finalStartPos,
- finalEndPos));
- assertEquals(finalCount, 1);
+ return search.getSearchEntries();
}
@Test(dependsOnMethods = {"testAdd", "testSearchIndex",
diff --git a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java
index 3b2d643..b278826 100644
--- a/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java
+++ b/opendj-sdk/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/types/SearchFilterTests.java
@@ -918,9 +918,12 @@
// These should be case insensitive
{"(SN=Smith)", "(sn=Smith)", true, true},
- {"(sn=smith)", "(sn=Smith)", true, false},
{"(SN=S*th)", "(sn=S*th)", true, true},
+ // We no longer normalize assertion values,
+ // so these filters are not equal
+ {"(sn=smith)", "(sn=Smith)", false, false},
+
{"(sn:caseExactMatch:=Smith)", "(sn:caseExactMatch:=Smith)", true, true},
// This demonstrates bug 704.
@@ -939,8 +942,10 @@
{"(sn;lang-en=Smith)", "(sn=Smith)", false, false},
- // This demonstrates bug 705.
- {"(sn=s*t*h)", "(sn=S*T*H)", true, false},
+ // This was initially to demonstrates bug 705.
+ // But we reverted back to old behavior,
+ // because we no longer normalize assertion values.
+ {"(sn=s*t*h)", "(sn=S*T*H)", false, false},
// These should be case sensitive
{"(labeledURI=http://opends.org)", "(labeledURI=http://OpenDS.org)", false, false},
--
Gitblit v1.10.0