From 8513213e8f8f1cd4d87a10b3218654c6988f5188 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 31 Mar 2015 10:00:47 +0000
Subject: [PATCH] CR-6474 OPENDJ-1711 - re-implement VLV support for pluggable backends
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java | 95 ++++++++++++++++++++++-------------------------
1 files changed, 45 insertions(+), 50 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index 2428237..8c1f0e0 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -27,12 +27,13 @@
*/
package org.opends.server.backends.pluggable;
-import static org.forgerock.util.Reject.checkNotNull;
import static org.forgerock.util.Utils.closeSilently;
import static org.opends.messages.JebMessages.*;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.IndexFilter.*;
import static org.opends.server.backends.pluggable.JebFormat.*;
+import static org.opends.server.backends.pluggable.VLVIndex.encodeTargetAssertion;
+import static org.opends.server.backends.pluggable.VLVIndex.encodeVLVKey;
import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.protocols.ldap.LDAPResultCode.*;
import static org.opends.server.types.AdditionalLogItem.*;
@@ -44,7 +45,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -783,7 +783,7 @@
storage.read(new ReadOperation<Void>()
{
@Override
- public Void run(ReadableTransaction txn) throws Exception
+ public Void run(final ReadableTransaction txn) throws Exception
{
DN aBaseDN = searchOperation.getBaseDN();
SearchScope searchScope = searchOperation.getScope();
@@ -870,7 +870,7 @@
{
try
{
- entryIDSet = vlvIndex.evaluate(null, searchOperation, sortRequest, vlvRequest, debugBuffer);
+ entryIDSet = vlvIndex.evaluate(txn, searchOperation, sortRequest, vlvRequest, debugBuffer);
if (entryIDSet != null)
{
searchOperation.addResponseControl(new ServerSideSortResponseControl(SUCCESS, null));
@@ -3208,7 +3208,7 @@
final SearchScope scope = searchOperation.getScope();
final SearchFilter filter = searchOperation.getFilter();
- final TreeMap<SortValues, Long> sortMap = new TreeMap<SortValues, Long>();
+ final TreeMap<ByteString, EntryID> sortMap = new TreeMap<ByteString, EntryID>();
for (EntryID id : entryIDSet)
{
try
@@ -3216,7 +3216,7 @@
Entry e = getEntry(txn, id);
if (e.matchesBaseAndScope(baseDN, scope) && filter.matchesEntry(e))
{
- sortMap.put(new SortValues(id, e, sortOrder), id.longValue());
+ sortMap.put(encodeVLVKey(sortOrder, e, id.longValue()), id);
}
}
catch (Exception e)
@@ -3238,83 +3238,81 @@
return sortByOffset(searchOperation, vlvRequest, sortMap);
}
- return sortByGreaterThanOrEqualAssertion(searchOperation, vlvRequest, sortMap);
+ return sortByGreaterThanOrEqualAssertion(searchOperation, vlvRequest, sortOrder, sortMap);
}
- /** FIXME: Might be moved into a util.Longs class */
- private static final long[] toArray(Collection<? extends Number> collection)
+ private static final long[] toArray(Collection<EntryID> entryIDs)
{
- checkNotNull(collection, "collection must not be null");
- final long[] array = new long[collection.size()];
+ final long[] array = new long[entryIDs.size()];
int i = 0;
- for (Number number : collection)
+ for (EntryID entryID : entryIDs)
{
- array[i++] = number.longValue();
+ array[i++] = entryID.longValue();
}
return array;
}
private static final EntryIDSet sortByGreaterThanOrEqualAssertion(SearchOperation searchOperation,
- VLVRequestControl vlvRequest, final TreeMap<SortValues, Long> sortMap)
+ VLVRequestControl vlvRequest, SortOrder sortOrder, final TreeMap<ByteString, EntryID> sortMap)
+ throws DirectoryException
{
ByteString assertionValue = vlvRequest.getGreaterThanOrEqualAssertion();
+ ByteSequence encodedTargetAssertion =
+ encodeTargetAssertion(sortOrder, assertionValue, searchOperation, sortMap.size());
boolean targetFound = false;
- int targetOffset = 0;
- int includedBeforeCount = 0;
+ int index = 0;
+ int targetIndex = 0;
+ int startIndex = 0;
int includedAfterCount = 0;
-
- LinkedList<Long> idList = new LinkedList<Long>();
- for (Map.Entry<SortValues, Long> entry : sortMap.entrySet())
+ long[] idSet = new long[sortMap.size()];
+ for (Map.Entry<ByteString, EntryID> entry : sortMap.entrySet())
{
- SortValues sortValues = entry.getKey();
- long id = entry.getValue().longValue();
+ ByteString vlvKey = entry.getKey();
+ EntryID id = entry.getValue();
+ idSet[index++] = id.longValue();
if (targetFound)
{
- idList.add(id);
includedAfterCount++;
- if (includedAfterCount >= vlvRequest.getBeforeCount())
+ if (includedAfterCount >= vlvRequest.getAfterCount())
{
break;
}
}
else
{
- targetFound = sortValues.compareTo(assertionValue) >= 0;
- targetOffset++;
-
+ targetFound = vlvKey.compareTo(encodedTargetAssertion) >= 0;
if (targetFound)
{
- idList.add(id);
+ startIndex = Math.max(0, targetIndex - vlvRequest.getBeforeCount());
}
- else if (vlvRequest.getBeforeCount() > 0)
- {
- idList.add(id);
- includedBeforeCount++;
- if (includedBeforeCount > vlvRequest.getBeforeCount())
- {
- idList.removeFirst();
- includedBeforeCount--;
- }
- }
+ targetIndex++;
}
}
- if (!targetFound)
+ final EntryIDSet result;
+ if (targetFound)
{
- // No entry was found to be greater than or equal to the sort key, so the target offset will be one greater
- // than the content count.
- targetOffset = sortMap.size() + 1;
+ final long[] array = new long[index - startIndex];
+ System.arraycopy(idSet, startIndex, array, 0, index);
+ result = newDefinedSet(array);
}
-
- searchOperation.addResponseControl(new VLVResponseControl(targetOffset, sortMap.size(), LDAPResultCode.SUCCESS));
-
- return newDefinedSet(toArray(idList));
+ else
+ {
+ /*
+ * No entry was found to be greater than or equal to the sort key, so the target offset will
+ * be one greater than the content count.
+ */
+ targetIndex = sortMap.size() + 1;
+ result = newDefinedSet();
+ }
+ searchOperation.addResponseControl(new VLVResponseControl(targetIndex, sortMap.size(), LDAPResultCode.SUCCESS));
+ return result;
}
private static final EntryIDSet sortByOffset(SearchOperation searchOperation, VLVRequestControl vlvRequest,
- TreeMap<SortValues, Long> sortMap) throws DirectoryException
+ TreeMap<ByteString, EntryID> sortMap) throws DirectoryException
{
int targetOffset = vlvRequest.getOffset();
if (targetOffset < 0)
@@ -3354,12 +3352,10 @@
}
int count = 1 + beforeCount + afterCount;
-
long[] sortedIDs = new long[count];
-
int treePos = 0;
int arrayPos = 0;
- for (Long id : sortMap.values())
+ for (EntryID id : sortMap.values())
{
if (treePos++ < startPos)
{
@@ -3381,7 +3377,6 @@
}
searchOperation.addResponseControl(new VLVResponseControl(targetOffset, sortMap.size(), LDAPResultCode.SUCCESS));
-
return newDefinedSet(sortedIDs);
}
--
Gitblit v1.10.0