From cc3c619853777f4120192017ac8fa04ee73438df Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Wed, 23 Dec 2015 11:10:17 +0000
Subject: [PATCH] OPENDJ-2575 VLV indexed search with offset type control does not give expected results
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java | 6 ++
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java | 128 +++++++++++++++++++++++++++++++-----------
2 files changed, 100 insertions(+), 34 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
index 14dc106..6504190 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/OnDiskMergeImporter.java
@@ -954,11 +954,11 @@
void beforeImport(EntryContainer entryContainer)
{
- clearEntryContainerTrees(entryContainer);
+ entryContainer.delete(asWriteableTransaction(importer));
visitIndexes(entryContainer, setTrust(false, importer));
}
- abstract Callable<Void> newPhaseTwoTask(TreeName treeName, Chunk chunk, PhaseTwoProgressReporter progressReporter);
+ abstract Callable<Void> newPhaseTwoTask(TreeName treeName, Chunk source, PhaseTwoProgressReporter progressReporter);
void afterImport(EntryContainer entryContainer)
{
@@ -979,30 +979,36 @@
newCollector(entryContainers.get(treeName.getBaseDN()), treeName), sorter);
}
- final Callable<Void> newChunkCopierTask(TreeName treeName, final Chunk chunk,
+ final Callable<Void> newChunkCopierTask(TreeName treeName, final Chunk source,
PhaseTwoProgressReporter progressReporter)
{
- return new ChunkCopierTask(progressReporter, chunk, treeName, importer);
+ return new ChunkCopierTask(progressReporter, source, treeName, importer);
}
- final Callable<Void> newDN2IDImporterTask(TreeName treeName, final Chunk chunk,
+ final Callable<Void> newDN2IDImporterTask(TreeName treeName, final Chunk source,
PhaseTwoProgressReporter progressReporter, boolean dn2idAlreadyImported)
{
final EntryContainer entryContainer = entryContainers.get(treeName.getBaseDN());
final ID2ChildrenCount id2count = entryContainer.getID2ChildrenCount();
- return new DN2IDImporterTask(progressReporter, importer, tempDir, bufferPool, entryContainer.getDN2ID(), chunk,
+ return new DN2IDImporterTask(progressReporter, importer, tempDir, bufferPool, entryContainer.getDN2ID(), source,
id2count, newCollector(entryContainer, id2count.getName()), dn2idAlreadyImported);
}
- static final Callable<Void> newFlushTask(final Chunk chunk)
+ final Callable<Void> newVLVIndexImporterTask(VLVIndex vlvIndex, final Chunk source,
+ PhaseTwoProgressReporter progressReporter)
+ {
+ return new VLVIndexImporterTask(progressReporter, source, vlvIndex, importer);
+ }
+
+ static final Callable<Void> newFlushTask(final Chunk source)
{
return new Callable<Void>()
{
@Override
public Void call() throws Exception
{
- try (final MeteredCursor<ByteString, ByteString> unusued = chunk.flip())
+ try (final MeteredCursor<ByteString, ByteString> unusued = source.flip())
{
// force flush
}
@@ -1042,18 +1048,24 @@
}
@Override
- public Callable<Void> newPhaseTwoTask(TreeName treeName, final Chunk chunk,
+ public Callable<Void> newPhaseTwoTask(TreeName treeName, final Chunk source,
PhaseTwoProgressReporter progressReporter)
{
+ final EntryContainer entryContainer = entryContainers.get(treeName.getBaseDN());
+
if (isID2Entry(treeName))
{
- return newFlushTask(chunk);
+ return newFlushTask(source);
}
else if (isDN2ID(treeName))
{
- return newDN2IDImporterTask(treeName, chunk, progressReporter, false);
+ return newDN2IDImporterTask(treeName, source, progressReporter, false);
}
- return newChunkCopierTask(treeName, chunk, progressReporter);
+ else if (isVLVIndex(entryContainer, treeName))
+ {
+ return newVLVIndexImporterTask(getVLVIndex(entryContainer, treeName), source, progressReporter);
+ }
+ return newChunkCopierTask(treeName, source, progressReporter);
}
}
@@ -1089,18 +1101,24 @@
}
@Override
- public Callable<Void> newPhaseTwoTask(TreeName treeName, final Chunk chunk,
+ public Callable<Void> newPhaseTwoTask(TreeName treeName, final Chunk source,
PhaseTwoProgressReporter progressReporter)
{
+ final EntryContainer entryContainer = entryContainers.get(treeName.getBaseDN());
+
if (isID2Entry(treeName))
{
- return newFlushTask(chunk);
+ return newFlushTask(source);
}
else if (isDN2ID(treeName))
{
- return newDN2IDImporterTask(treeName, chunk, progressReporter, true);
+ return newDN2IDImporterTask(treeName, source, progressReporter, true);
}
- return newChunkCopierTask(treeName, chunk, progressReporter);
+ else if (isVLVIndex(entryContainer, treeName))
+ {
+ return newVLVIndexImporterTask(getVLVIndex(entryContainer, treeName), source, progressReporter);
+ }
+ return newChunkCopierTask(treeName, source, progressReporter);
}
@Override
@@ -1161,7 +1179,7 @@
void beforeImport(EntryContainer entryContainer)
{
visitIndexes(entryContainer, visitOnlyIndexes(indexesToRebuild, setTrust(false, importer)));
- visitIndexes(entryContainer, visitOnlyIndexes(indexesToRebuild, clearDatabase(importer)));
+ visitIndexes(entryContainer, visitOnlyIndexes(indexesToRebuild, deleteDatabase(importer)));
}
@Override
@@ -1182,18 +1200,24 @@
}
@Override
- public Callable<Void> newPhaseTwoTask(TreeName treeName, Chunk chunk, PhaseTwoProgressReporter progressReporter)
+ public Callable<Void> newPhaseTwoTask(TreeName treeName, Chunk source, PhaseTwoProgressReporter progressReporter)
{
+ final EntryContainer entryContainer = entryContainers.get(treeName.getBaseDN());
+
if (indexesToRebuild.contains(treeName.getIndexId().toLowerCase()))
{
if (isDN2ID(treeName))
{
- return newDN2IDImporterTask(treeName, chunk, progressReporter, false);
+ return newDN2IDImporterTask(treeName, source, progressReporter, false);
}
- return newChunkCopierTask(treeName, chunk, progressReporter);
+ else if (isVLVIndex(entryContainer, treeName))
+ {
+ return newVLVIndexImporterTask(getVLVIndex(entryContainer, treeName), source, progressReporter);
+ }
+ return newChunkCopierTask(treeName, source, progressReporter);
}
// Do nothing (flush null chunk)
- return newFlushTask(chunk);
+ return newFlushTask(source);
}
@Override
@@ -2207,12 +2231,43 @@
}
}
- private static void copyIntoChunk(SequentialCursor<ByteString, ByteString> source, Chunk destination)
+ /** Task to copy VLV's counter chunks into a database tree. */
+ private static final class VLVIndexImporterTask implements Callable<Void>
{
+ private final PhaseTwoProgressReporter reporter;
+ private final VLVIndex vlvIndex;
+ private final Importer destination;
+ private final Chunk source;
+
+ VLVIndexImporterTask(PhaseTwoProgressReporter reporter, Chunk source, VLVIndex vlvIndex, Importer destination)
+ {
+ this.source = source;
+ this.vlvIndex = vlvIndex;
+ this.destination = destination;
+ this.reporter = reporter;
+ }
+
+ @Override
+ public Void call()
+ {
+ try (final SequentialCursor<ByteString, ByteString> sourceCursor = trackCursorProgress(reporter, source.flip()))
+ {
+ final long nbRecords = copyIntoChunk(sourceCursor, asChunk(vlvIndex.getName(), destination));
+ vlvIndex.importCount(destination, nbRecords);
+ return null;
+ }
+ }
+ }
+
+ private static long copyIntoChunk(SequentialCursor<ByteString, ByteString> source, Chunk destination)
+ {
+ long nbRecords = 0;
while (source.next())
{
destination.put(source.getKey(), source.getValue());
+ nbRecords++;
}
+ return nbRecords;
}
/**
@@ -3079,14 +3134,19 @@
private static boolean isVLVIndex(EntryContainer entryContainer, TreeName treeName)
{
+ return getVLVIndex(entryContainer, treeName) != null;
+ }
+
+ private static VLVIndex getVLVIndex(EntryContainer entryContainer, TreeName treeName)
+ {
for (VLVIndex vlvIndex : entryContainer.getVLVIndexes())
{
if (treeName.equals(vlvIndex.getName()))
{
- return true;
+ return vlvIndex;
}
}
- return false;
+ return null;
}
private static DefaultIndex getIndex(EntryContainer entryContainer, TreeName treeName)
@@ -3430,17 +3490,17 @@
}
}
- private static IndexVisitor clearDatabase(Importer importer)
+ private static IndexVisitor deleteDatabase(Importer importer)
{
- return new ClearDatabase(importer);
+ return new DeleteDatabase(importer);
}
/** Delete & recreate the database of the visited indexes. */
- private static final class ClearDatabase implements IndexVisitor
+ private static final class DeleteDatabase implements IndexVisitor
{
private final Importer importer;
- ClearDatabase(Importer importer)
+ DeleteDatabase(Importer importer)
{
this.importer = importer;
}
@@ -3448,24 +3508,24 @@
@Override
public void visitAttributeIndex(Index index)
{
- clearTree(index);
+ deleteTree(index);
}
@Override
public void visitVLVIndex(VLVIndex index)
{
- clearTree(index);
+ deleteTree(index);
}
@Override
public void visitSystemIndex(Tree index)
{
- clearTree(index);
+ deleteTree(index);
}
- private void clearTree(Tree index)
+ private void deleteTree(Tree index)
{
- importer.clearTree(index.getName());
+ index.delete(asWriteableTransaction(importer));
}
}
@@ -3705,7 +3765,7 @@
@Override
public void deleteTree(TreeName name)
{
- throw new UnsupportedOperationException();
+ importer.clearTree(name);
}
@Override
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
index cb4e723..8512ece 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java
@@ -54,6 +54,7 @@
import org.opends.server.admin.std.server.BackendVLVIndexCfg;
import org.opends.server.backends.pluggable.State.IndexFlag;
import org.opends.server.backends.pluggable.spi.Cursor;
+import org.opends.server.backends.pluggable.spi.Importer;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
@@ -174,6 +175,11 @@
counter.delete(txn);
}
+ void importCount(Importer importer, long count)
+ {
+ counter.importPut(importer, COUNT_KEY, count);
+ }
+
@Override
public synchronized boolean isConfigurationChangeAcceptable(final BackendVLVIndexCfg cfg,
final List<LocalizableMessage> unacceptableReasons)
--
Gitblit v1.10.0