From ffe47ffdf1b70a54ed566cde26ad343125109500 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 18 Dec 2014 22:56:40 +0000
Subject: [PATCH] OPENDJ-1602 (CR-5566) New pluggable storage based backend
---
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java | 324 +++++++++++++++++++++++++++++++----------------------
1 files changed, 188 insertions(+), 136 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java
index 0050067..c45d76b 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java
@@ -26,6 +26,9 @@
*/
package org.opends.server.backends.pluggable;
+
+
+import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -89,12 +92,10 @@
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
- /** The comparator for vlvIndex keys. */
- public VLVKeyComparator comparator;
/** The limit on the number of entry IDs that may be indexed by one key. */
private int sortedSetCapacity = 4000;
/** The SortOrder in use by this VLV index to sort the entries. */
- public SortOrder sortOrder;
+ private SortOrder sortOrder;
/** The cached count of entries in this index. */
private final AtomicInteger count;
@@ -129,7 +130,7 @@
* @throws ConfigException if a error occurs while reading the VLV index
* configuration
*/
- public VLVIndex(BackendVLVIndexCfg config, State state, Storage env,
+ VLVIndex(BackendVLVIndexCfg config, State state, Storage env,
EntryContainer entryContainer, ReadableStorage txn)
throws StorageRuntimeException, ConfigException
{
@@ -151,48 +152,7 @@
throw new ConfigException(msg);
}
- String[] sortAttrs = config.getSortOrder().split(" ");
- SortKey[] sortKeys = new SortKey[sortAttrs.length];
- MatchingRule[] orderingRules = new MatchingRule[sortAttrs.length];
- boolean[] ascending = new boolean[sortAttrs.length];
- for(int i = 0; i < sortAttrs.length; i++)
- {
- try
- {
- if(sortAttrs[i].startsWith("-"))
- {
- ascending[i] = false;
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- else
- {
- ascending[i] = true;
- if(sortAttrs[i].startsWith("+"))
- {
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- }
- }
- catch(Exception e)
- {
- throw new ConfigException(ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortKeys[i], treeName));
- }
-
- AttributeType attrType =
- DirectoryServer.getAttributeType(sortAttrs[i].toLowerCase());
- if(attrType == null)
- {
- LocalizableMessage msg =
- ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortAttrs[i], treeName);
- throw new ConfigException(msg);
- }
- sortKeys[i] = new SortKey(attrType, ascending[i]);
- orderingRules[i] = attrType.getOrderingMatchingRule();
- }
-
- this.sortOrder = new SortOrder(sortKeys);
- this.comparator = new VLVKeyComparator(orderingRules, ascending);
-
+ this.sortOrder = new SortOrder(parseSortKeys(config));
this.state = state;
this.trusted = state.getIndexTrustState(txn, this);
if (!trusted && entryContainer.getHighestEntryID(txn).longValue() == 0)
@@ -206,6 +166,49 @@
this.config.addChangeListener(this);
}
+ private SortKey[] parseSortKeys(BackendVLVIndexCfg config)
+ throws ConfigException
+ {
+ String[] sortAttrs = config.getSortOrder().split(" ");
+ SortKey[] sortKeys = new SortKey[sortAttrs.length];
+ for (int i = 0; i < sortAttrs.length; i++)
+ {
+ final boolean ascending;
+ try
+ {
+ if (sortAttrs[i].startsWith("-"))
+ {
+ ascending = false;
+ sortAttrs[i] = sortAttrs[i].substring(1);
+ }
+ else
+ {
+ ascending = true;
+ if (sortAttrs[i].startsWith("+"))
+ {
+ sortAttrs[i] = sortAttrs[i].substring(1);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new ConfigException(ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(
+ sortKeys[i], treeName));
+ }
+
+ AttributeType attrType = DirectoryServer.getAttributeType(sortAttrs[i]
+ .toLowerCase());
+ if (attrType == null)
+ {
+ LocalizableMessage msg = ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(
+ sortAttrs[i], treeName);
+ throw new ConfigException(msg);
+ }
+ sortKeys[i] = new SortKey(attrType, ascending);
+ }
+ return sortKeys;
+ }
+
private SearchScope valueOf(Scope cfgScope)
{
final Enum toFind = SearchScope.Enum.valueOf(cfgScope.name());
@@ -394,7 +397,7 @@
* JE database.
* @throws DirectoryException If a Directory Server error occurs.
*/
- public SortValuesSet getSortValuesSet(ReadableStorage txn, long entryID,
+ private SortValuesSet getSortValuesSet(ReadableStorage txn, long entryID,
ByteString[] values, AttributeType[] types) throws StorageRuntimeException,
DirectoryException
{
@@ -520,7 +523,7 @@
while(true)
{
- ByteString key;
+ final ByteString key;
if(av != null)
{
if(dv != null)
@@ -1111,16 +1114,6 @@
}
/**
- * Get the sorted set capacity configured for this VLV index.
- *
- * @return The sorted set capacity.
- */
- public int getSortedSetCapacity()
- {
- return sortedSetCapacity;
- }
-
- /**
* Indicates if the given entry should belong in this VLV index.
*
* @param entry The entry to check.
@@ -1154,43 +1147,14 @@
return false;
}
- String[] sortAttrs = cfg.getSortOrder().split(" ");
- SortKey[] sortKeys = new SortKey[sortAttrs.length];
- MatchingRule[] orderingRules = new MatchingRule[sortAttrs.length];
- boolean[] ascending = new boolean[sortAttrs.length];
- for(int i = 0; i < sortAttrs.length; i++)
+ try
{
- try
- {
- if(sortAttrs[i].startsWith("-"))
- {
- ascending[i] = false;
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- else
- {
- ascending[i] = true;
- if(sortAttrs[i].startsWith("+"))
- {
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- }
- }
- catch(Exception e)
- {
- unacceptableReasons.add(ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortKeys[i], treeName));
- return false;
- }
-
- AttributeType attrType = DirectoryServer.getAttributeType(sortAttrs[i].toLowerCase());
- if(attrType == null)
- {
- LocalizableMessage msg = ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortAttrs[i], treeName);
- unacceptableReasons.add(msg);
- return false;
- }
- sortKeys[i] = new SortKey(attrType, ascending[i]);
- orderingRules[i] = attrType.getOrderingMatchingRule();
+ parseSortKeys(cfg);
+ }
+ catch (ConfigException e)
+ {
+ unacceptableReasons.add(e.getMessageObject());
+ return false;
}
return true;
@@ -1268,50 +1232,15 @@
// Update the sort order only if changed.
if (!config.getSortOrder().equals(cfg.getSortOrder()))
{
- String[] sortAttrs = cfg.getSortOrder().split(" ");
- SortKey[] sortKeys = new SortKey[sortAttrs.length];
- MatchingRule[] orderingRules = new MatchingRule[sortAttrs.length];
- boolean[] ascending = new boolean[sortAttrs.length];
- for(int i = 0; i < sortAttrs.length; i++)
+ try
{
- try
- {
- if(sortAttrs[i].startsWith("-"))
- {
- ascending[i] = false;
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- else
- {
- ascending[i] = true;
- if(sortAttrs[i].startsWith("+"))
- {
- sortAttrs[i] = sortAttrs[i].substring(1);
- }
- }
- }
- catch(Exception e)
- {
- ccr.addMessage(ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortKeys[i], treeName));
- ccr.setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
- }
-
- AttributeType attrType =
- DirectoryServer.getAttributeType(sortAttrs[i].toLowerCase());
- if(attrType == null)
- {
- ccr.addMessage(ERR_JEB_CONFIG_VLV_INDEX_UNDEFINED_ATTR.get(sortKeys[i], treeName));
- ccr.setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
- }
- else
- {
- sortKeys[i] = new SortKey(attrType, ascending[i]);
- orderingRules[i] = attrType.getOrderingMatchingRule();
- }
+ this.sortOrder = new SortOrder(parseSortKeys(cfg));
}
-
- this.sortOrder = new SortOrder(sortKeys);
- this.comparator = new VLVKeyComparator(orderingRules, ascending);
+ catch (ConfigException e)
+ {
+ ccr.addMessage(e.getMessageObject());
+ ccr.setResultCode(ResultCode.INVALID_ATTRIBUTE_SYNTAX);
+ }
// We have to close the database and open it using the new comparator.
entryContainer.exclusiveLock.lock();
@@ -1357,4 +1286,127 @@
this.config = cfg;
}
+
+ /**
+ * Compares the contents in the provided values set with the given values to
+ * determine their relative order. A null value is always considered greater
+ * then a non null value. If all attribute values are the same, the entry ID
+ * will be used to determine the ordering. If the given attribute values array
+ * does not contain all the values in the sort order, any missing values will
+ * be considered as a unknown or wildcard value instead of a non existent
+ * value. When comparing partial information, only values available in both
+ * the values set and the given values will be used to determine the ordering.
+ * If all available information is the same, 0 will be returned.
+ *
+ * @param set
+ * The sort values set to containing the values.
+ * @param index
+ * The index of the values in the set.
+ * @param entryID
+ * The entry ID to use in the comparison.
+ * @param values
+ * The values to use in the comparison.
+ * @return A negative integer if the values in the set should come before the
+ * given values in ascending order, a positive integer if the values
+ * in the set should come after the given values in ascending order,
+ * or zero if there is no difference between the values with regard to
+ * ordering.
+ * @throws StorageRuntimeException
+ * If an error occurs during an operation on a JE database.
+ * @throws DirectoryException
+ * If an error occurs while trying to normalize the value (e.g., if
+ * it is not acceptable for use with the associated equality
+ * matching rule).
+ */
+ int compare(SortValuesSet set, int index, long entryID,
+ ByteSequence... values) throws StorageRuntimeException,
+ DirectoryException
+ {
+ SortKey[] sortKeys = sortOrder.getSortKeys();
+ for (int j = 0; j < sortKeys.length; j++)
+ {
+ MatchingRule orderingRule = sortKeys[j].getOrderingRule();
+ boolean ascending = sortKeys[j].ascending();
+
+ if (j >= values.length)
+ {
+ break;
+ }
+
+ ByteString b1Bytes = set.getValue((index * sortKeys.length) + j);
+ ByteString b2Bytes = null;
+
+ if (values[j] != null)
+ {
+ try
+ {
+ b2Bytes = orderingRule.normalizeAttributeValue(values[j]);
+ }
+ catch (DecodeException e)
+ {
+ throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX,
+ e.getMessageObject(), e);
+ }
+ }
+
+ // A null value will always come after a non-null value.
+ if (b1Bytes == null)
+ {
+ if (b2Bytes == null)
+ {
+ continue;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else if (b2Bytes == null)
+ {
+ return -1;
+ }
+
+ final Comparator<ByteSequence> comp = orderingRule.comparator();
+ final int result = ascending ? comp.compare(b1Bytes, b2Bytes) : comp
+ .compare(b2Bytes, b1Bytes);
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+
+ if (entryID != -1)
+ {
+ // If we've gotten here, then we can't tell a difference between the sets
+ // of values, so sort based on entry ID.
+ return compare(set.getEntryIDs()[index], entryID);
+ }
+
+ // If we've gotten here, then we can't tell the difference between the sets
+ // of available values and the entry ID is not available. Just return 0.
+ return 0;
+ }
+
+ private int compare(long l1, long l2)
+ {
+ final long difference = l1 - l2;
+ if (difference < 0)
+ {
+ return -1;
+ }
+ else if (difference > 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ SortOrder getSortOrder()
+ {
+ return sortOrder;
+ }
}
--
Gitblit v1.10.0