From df310fa66969c2058dbb1f8f23e90a4d717df44c Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 02 Apr 2015 10:16:45 +0000
Subject: [PATCH] OPENDJ-1711 - re-implement VLV support for pluggable backends
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/VLVIndex.java | 50 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 37 insertions(+), 13 deletions(-)
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 0c865cc..b8f037c 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
@@ -607,7 +607,7 @@
final ByteStringBuilder encodedPrimaryKey = new ByteStringBuilder(assertion.length() + 10);
final MatchingRule matchingRule = primarySortKey.getAttributeType().getOrderingMatchingRule();
final ByteString normalizedAttributeValue = matchingRule.normalizeAttributeValue(assertion);
- encodeVLVKeyValue(primarySortKey, normalizedAttributeValue, encodedPrimaryKey);
+ encodeVLVKeyValue(normalizedAttributeValue, encodedPrimaryKey, primarySortKey.ascending());
return encodedPrimaryKey;
}
catch (final DecodeException e)
@@ -803,37 +803,61 @@
}
}
}
- encodeVLVKeyValue(sortKey, sortValue, builder);
+ encodeVLVKeyValue(sortValue, builder, sortKey.ascending());
}
}
- private static void encodeVLVKeyValue(final SortKey sortKey, final ByteString normalizedAttributeValue,
- final ByteStringBuilder builder)
+ /**
+ * Package private for testing.
+ * <p>
+ * Keys are logically encoded as follows:
+ * <ul>
+ * <li>if the key is {@code null} then append {@code 0xff} in order to ensure that all
+ * {@code null} keys sort after non-{@code null} keys in ascending order
+ * <li>else
+ * <ul>
+ * <li>escape any bytes that look like a separator byte ({@code 0x00}) or a separator escape byte
+ * ({@code 0x01}) by prefixing the byte with a separator escape byte ({@code 0x01})
+ * <li>escape the first byte if it looks like a null key byte ({@code 0xff}) or a null key escape
+ * byte ({@code 0xfe}) by prefixing the byte with a null key escape byte ({@code 0xfe})
+ * </ul>
+ * <li>append a separator byte ({@code 0x00}) which will be used for distinguishing between the
+ * end of the key and the start of the next key
+ * <li>invert all the bytes if the sort order is descending.
+ * </ul>
+ */
+ static void encodeVLVKeyValue(final ByteString keyBytes, final ByteStringBuilder builder,
+ final boolean ascending)
{
- final boolean ascending = sortKey.ascending();
final byte separator = ascending ? (byte) 0x00 : (byte) 0xff;
- if (normalizedAttributeValue != null)
+ if (keyBytes != null)
{
- // Ensure that all keys sort before (ascending) or after (descending) missing keys.
- builder.append(separator);
-
final byte escape = ascending ? (byte) 0x01 : (byte) 0xfe;
final byte sortOrderMask = separator;
- final int length = normalizedAttributeValue.length();
+ final int length = keyBytes.length();
for (int i = 0; i < length; i++)
{
- final byte b = normalizedAttributeValue.byteAt(i);
- if (b == separator || b == escape)
+ final byte b = keyBytes.byteAt(i);
+ if ((b & (byte) 0x01) == b)
{
+ // Escape bytes that look like a separator.
builder.append(escape);
}
+ else if (i == 0 && (b & (byte) 0xfe) == (byte) 0xfe)
+ {
+ /*
+ * Ensure that all keys sort before (ascending) or after (descending) null keys, by
+ * escaping the first byte if it looks like a null key.
+ */
+ builder.append((byte) ~escape);
+ }
// Invert the bits if this key is in descending order.
builder.append((byte) (b ^ sortOrderMask));
}
}
else
{
- // Ensure that missing keys sort after (ascending) or before (descending) all other keys.
+ // Ensure that null keys sort after (ascending) or before (descending) all other keys.
builder.append(ascending ? (byte) 0xff : (byte) 0x00);
}
builder.append(separator);
--
Gitblit v1.10.0