From 2f13f91c158747ca997a44d8e61830f46b77dd82 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 14 Mar 2014 11:31:24 +0000
Subject: [PATCH] OPENDJ-1308 (CR-3156) Migrate schema support - ByteString - Indexer

---
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java                          |   53 ++++
 opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java |   37 ++-
 opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java   |   40 ++-
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/Index.java                                   |   96 ++++----
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/Indexer.java                                 |   46 +++-
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java                     |   20 
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/PresenceIndexer.java                         |   58 ++---
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/VerifyJob.java                               |   30 +-
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2SIndexer.java                             |   41 +--
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java                              |   28 ++
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2CIndexer.java                             |   41 +--
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java                          |   31 +-
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/NullIndex.java                               |   11 
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexBuffer.java                             |   60 ++--
 opendj3-server-dev/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java                     |   50 ---
 15 files changed, 337 insertions(+), 305 deletions(-)

diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
index b646ad4..6740516 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/AttributeIndex.java
@@ -1313,6 +1313,59 @@
   }
 
   /**
+   * Byte string key comparator. The default lexicographic byte string
+   * comparator.
+   * <p>
+   * This is the byte string equivalent of {@link KeyComparator}.
+   * <p>
+   * Note: Matt reckons we could simply use ByteString.compareTo(),
+   * but I am using this for now as an intermediate step.
+   */
+  public static class BSKeyComparator implements Comparator<ByteString>
+  {
+    /**
+     * Compares its two arguments for order. Returns a negative integer, zero,
+     * or a positive integer as the first argument is less than, equal to, or
+     * greater than the second.
+     *
+     * @param a
+     *          the first object to be compared.
+     * @param b
+     *          the second object to be compared.
+     * @return a negative integer, zero, or a positive integer as the first
+     *         argument is less than, equal to, or greater than the second.
+     */
+    @Override
+    public int compare(ByteString a, ByteString b)
+    {
+      int i;
+      for (i = 0; i < a.length() && i < b.length(); i++)
+      {
+        if (a.byteAt(i) > b.byteAt(i))
+        {
+          return 1;
+        }
+        else if (a.byteAt(i) < b.byteAt(i))
+        {
+          return -1;
+        }
+      }
+      if (a.length() == b.length())
+      {
+        return 0;
+      }
+      if (a.length() > b.length())
+      {
+        return 1;
+      }
+      else
+      {
+        return -1;
+      }
+    }
+  }
+
+  /**
    * Retrieve the entry IDs that might match an approximate filter.
    *
    * @param approximateFilter The approximate filter.
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
index be47502..0545cd7 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -34,7 +34,9 @@
 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.ByteString;
+import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.opendj.ldap.SearchScope;
 import org.opends.server.admin.server.ConfigurationAddListener;
 import org.opends.server.admin.server.ConfigurationChangeListener;
@@ -46,12 +48,10 @@
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.EntryCache;
 import org.opends.server.api.plugin.PluginResult;
-import org.forgerock.opendj.config.server.ConfigException;
 import org.opends.server.controls.*;
 import org.opends.server.core.*;
 import org.opends.server.protocols.ldap.LDAPResultCode;
 import org.opends.server.types.*;
-import org.forgerock.opendj.ldap.ResultCode;
 import org.opends.server.util.ServerConstants;
 import org.opends.server.util.StaticUtils;
 
@@ -2045,8 +2045,7 @@
     // Remove the id2c and id2s records for this entry.
     if(indexBuffer != null)
     {
-      byte[] leafIDKeyBytes =
-        JebFormat.entryIDToDatabase(leafID.longValue());
+      ByteString leafIDKeyBytes = ByteString.valueOf(leafID.longValue());
       id2children.delete(indexBuffer, leafIDKeyBytes);
       id2subtree.delete(indexBuffer, leafIDKeyBytes);
     }
@@ -2073,8 +2072,7 @@
 
       if(indexBuffer != null)
       {
-        byte[] parentIDBytes =
-          JebFormat.entryIDToDatabase(parentID.longValue());
+        ByteString parentIDBytes = ByteString.valueOf(parentID.longValue());
         // Remove from id2children.
         if (isParent)
         {
@@ -2636,15 +2634,12 @@
     // Add the new ID to id2children and id2subtree of new apex parent entry.
     if(isApexEntryMoved)
     {
-      EntryID parentID;
-      byte[] parentIDKeyBytes;
       boolean isParent = true;
       for (DN dn = getParentWithinBase(newEntry.getName()); dn != null;
            dn = getParentWithinBase(dn))
       {
-        parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
-        parentIDKeyBytes =
-            JebFormat.entryIDToDatabase(parentID.longValue());
+        EntryID parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
+        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
         if(isParent)
         {
           id2children.insertID(buffer, parentIDKeyBytes, newID);
@@ -2685,14 +2680,11 @@
     // the old apex parent entry.
     if(oldSuperiorDN != null && isApexEntryMoved)
     {
-      EntryID parentID;
-      byte[] parentIDKeyBytes;
       boolean isParent = true;
       for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
       {
-        parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
-        parentIDKeyBytes =
-          JebFormat.entryIDToDatabase(parentID.longValue());
+        EntryID parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
+        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
         if(isParent)
         {
           id2children.removeID(buffer, parentIDKeyBytes, oldID);
@@ -2706,7 +2698,7 @@
     {
       // All the subordinates will be renumbered so we have to rebuild
       // id2c and id2s with the new ID.
-      byte[] oldIDKeyBytes = JebFormat.entryIDToDatabase(oldID.longValue());
+      ByteString oldIDKeyBytes = ByteString.valueOf(oldID.longValue());
       id2children.delete(buffer, oldIDKeyBytes);
       id2subtree.delete(buffer, oldIDKeyBytes);
 
@@ -2800,8 +2792,7 @@
       for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
       {
         EntryID parentID = dn2id.get(txn, dn, LockMode.DEFAULT);
-        byte[] parentIDKeyBytes =
-          JebFormat.entryIDToDatabase(parentID.longValue());
+        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
         id2subtree.removeID(buffer, parentIDKeyBytes, oldID);
       }
     }
@@ -2810,7 +2801,7 @@
     {
       // All the subordinates will be renumbered so we have to rebuild
       // id2c and id2s with the new ID.
-      byte[] oldIDKeyBytes = JebFormat.entryIDToDatabase(oldID.longValue());
+      ByteString oldIDKeyBytes = ByteString.valueOf(oldID.longValue());
       id2children.delete(buffer, oldIDKeyBytes);
       id2subtree.delete(buffer, oldIDKeyBytes);
 
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java
index b9eff78..c9d8a2a 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java
@@ -22,12 +22,15 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
-import java.util.Iterator;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
+
+import org.forgerock.opendj.ldap.ByteString;
 
 /**
  * Represents a set of Entry IDs.  It can represent a set where the IDs are
@@ -53,7 +56,7 @@
    * The database key containing this set, if the set was constructed
    * directly from the database.
    */
-  private byte[] keyBytes = null;
+  private ByteString keyBytes;
 
   /**
    * Create a new undefined set.
@@ -83,6 +86,19 @@
    */
   public EntryIDSet(byte[] keyBytes, byte[] bytes)
   {
+    this(keyBytes != null ? ByteString.wrap(keyBytes) : null, bytes);
+  }
+
+  /**
+   * Create a new entry ID set from the raw database value.
+   *
+   * @param keyBytes
+   *          The database key that contains this value.
+   * @param bytes
+   *          The database value, or null if there are no entry IDs.
+   */
+  public EntryIDSet(ByteString keyBytes, byte[] bytes)
+  {
     this.keyBytes = keyBytes;
 
     if (bytes == null)
@@ -189,11 +205,11 @@
     long[] n1 = new long[n.length];
     long last = -1;
     int j = 0;
-    for (int i = 0; i < n.length; i++)
+    for (long l : n)
     {
-      if (n[i] != last)
+      if (l != last)
       {
-        last = n1[j++] = n[i];
+        last = n1[j++] = l;
       }
     }
     if (j == n1.length)
@@ -229,6 +245,7 @@
    * Get a string representation of this object.
    * @return A string representation of this object.
    */
+  @Override
   public String toString()
   {
     StringBuilder buffer = new StringBuilder(16);
@@ -679,6 +696,7 @@
    *
    * @return An EntryID iterator.
    */
+  @Override
   public Iterator<EntryID> iterator()
   {
     if (values == null)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2CIndexer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2CIndexer.java
index 04e66c7..4c2d6e5 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2CIndexer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2CIndexer.java
@@ -22,28 +22,24 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
+import java.util.*;
+
+import org.forgerock.opendj.ldap.ByteString;
 import org.opends.server.types.Entry;
 import org.opends.server.types.Modification;
 
 import com.sleepycat.je.DatabaseEntry;
 
-import java.util.*;
-
 /**
  * Implementation of an Indexer for the children index.
  */
 public class ID2CIndexer extends Indexer
 {
   /**
-   * The comparator for keys generated by this class.
-   */
-  private static final Comparator<byte[]> comparator =
-       new AttributeIndex.KeyComparator();
-
-  /**
    * Create a new indexer for a children index.
    */
   public ID2CIndexer()
@@ -56,42 +52,33 @@
    * used to name an index created using this object.
    * @return A string representation of this object.
    */
+  @Override
   public String toString()
   {
     return "id2children";
   }
 
   /**
-   * Get the comparator that must be used to compare index keys
-   * generated by this class.
-   *
-   * @return A byte array comparator.
-   */
-  public Comparator<byte[]> getComparator()
-  {
-    return comparator;
-  }
-
-  /**
    * Generate the set of index keys for an entry.
    *
    * @param entry The entry.
    * @param addKeys The set into which the generated keys will be inserted.
    */
-  public void indexEntry(Entry entry, Set<byte[]> addKeys)
+  @Override
+  public void indexEntry(Entry entry, Set<ByteString> addKeys)
   {
     // The superior entry IDs are in the entry attachment.
-    ArrayList ids = (ArrayList)entry.getAttachment();
+    ArrayList<EntryID> ids = (ArrayList<EntryID>) entry.getAttachment();
 
     // Skip the entry's own ID.
-    Iterator iter = ids.iterator();
+    Iterator<EntryID> iter = ids.iterator();
     iter.next();
 
     // Get the parent ID.
     if (iter.hasNext())
     {
-      DatabaseEntry nodeIDData = ((EntryID)iter.next()).getDatabaseEntry();
-      addKeys.add(nodeIDData.getData());
+      DatabaseEntry nodeIDData = iter.next().getDatabaseEntry();
+      addKeys.add(ByteString.wrap(nodeIDData.getData()));
     }
   }
 
@@ -103,8 +90,9 @@
    * @param newEntry The new entry contents.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void replaceEntry(Entry oldEntry, Entry newEntry,
-                           Map<byte[], Boolean> modifiedKeys)
+                           Map<ByteString, Boolean> modifiedKeys)
   {
     // Nothing to do.
   }
@@ -120,9 +108,10 @@
    * @param mods The set of modifications that were applied to the entry.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void modifyEntry(Entry oldEntry, Entry newEntry,
                           List<Modification> mods,
-                          Map<byte[], Boolean> modifiedKeys)
+                          Map<ByteString, Boolean> modifiedKeys)
   {
     // Nothing to do.
   }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2SIndexer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2SIndexer.java
index 779552d..802c348 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2SIndexer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2SIndexer.java
@@ -22,28 +22,24 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
+import java.util.*;
+
+import org.forgerock.opendj.ldap.ByteString;
 import org.opends.server.types.Entry;
 import org.opends.server.types.Modification;
 
 import com.sleepycat.je.DatabaseEntry;
 
-import java.util.*;
-
 /**
  * Implementation of an Indexer for the subtree index.
  */
 public class ID2SIndexer extends Indexer
 {
   /**
-   * The comparator for keys generated by this class.
-   */
-  private static final Comparator<byte[]> comparator =
-       new AttributeIndex.KeyComparator();
-
-  /**
    * Create a new indexer for a subtree index.
    */
   public ID2SIndexer()
@@ -55,42 +51,33 @@
    * used to name an index created using this object.
    * @return A string representation of this object.
    */
+  @Override
   public String toString()
   {
     return "id2subtree";
   }
 
   /**
-   * Get the comparator that must be used to compare index keys
-   * generated by this class.
-   *
-   * @return A byte array comparator.
-   */
-  public Comparator<byte[]> getComparator()
-  {
-    return comparator;
-  }
-
-  /**
    * Generate the set of index keys for an entry.
    *
    * @param entry The entry.
    * @param addKeys The set into which the generated keys will be inserted.
    */
-  public void indexEntry(Entry entry, Set<byte[]> addKeys)
+  @Override
+  public void indexEntry(Entry entry, Set<ByteString> addKeys)
   {
     // The superior entry IDs are in the entry attachment.
-    ArrayList ids = (ArrayList)entry.getAttachment();
+    ArrayList<EntryID> ids = (ArrayList<EntryID>) entry.getAttachment();
 
     // Skip the entry's own ID.
-    Iterator iter = ids.iterator();
+    Iterator<EntryID> iter = ids.iterator();
     iter.next();
 
     // Iterate through the superior IDs.
     while (iter.hasNext())
     {
-      DatabaseEntry nodeIDData = ((EntryID)iter.next()).getDatabaseEntry();
-      addKeys.add(nodeIDData.getData());
+      DatabaseEntry nodeIDData = iter.next().getDatabaseEntry();
+      addKeys.add(ByteString.wrap(nodeIDData.getData()));
     }
   }
 
@@ -102,8 +89,9 @@
    * @param newEntry The new entry contents.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void replaceEntry(Entry oldEntry, Entry newEntry,
-                           Map<byte[], Boolean> modifiedKeys)
+                           Map<ByteString, Boolean> modifiedKeys)
   {
     // Nothing to do.
   }
@@ -119,9 +107,10 @@
    * @param mods The set of modifications that were applied to the entry.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void modifyEntry(Entry oldEntry, Entry newEntry,
                           List<Modification> mods,
-                          Map<byte[], Boolean> modifiedKeys)
+                          Map<ByteString, Boolean> modifiedKeys)
   {
     // Nothing to do.
   }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Index.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Index.java
index c575ff2..9b13a57 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Index.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Index.java
@@ -29,6 +29,7 @@
 import java.util.*;
 
 import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
 import org.opends.server.backends.jeb.importLDIF.ImportIDSet;
 import org.opends.server.types.DirectoryException;
@@ -61,6 +62,11 @@
   private final Comparator<byte[]> comparator;
 
   /**
+   * The comparator for index keys.
+   */
+  private final Comparator<ByteString> bsComparator;
+
+  /**
    * The limit on the number of entry IDs that may be indexed by one key.
    */
   private int indexEntryLimit;
@@ -106,8 +112,8 @@
    * A flag to indicate if a rebuild process is running on this index.
    * During the rebuild process, we assume that no entryIDSets are
    * accurate and return an undefined set on all read operations.
-   * However all write opeations will succeed. The rebuildRunning
-   * flag overrides all behaviours of the trusted flag.
+   * However all write operations will succeed. The rebuildRunning
+   * flag overrides all behaviors of the trusted flag.
    */
   private boolean rebuildRunning = false;
 
@@ -126,7 +132,7 @@
    * @param cursorEntryLimit The configured limit on the number of entry IDs
    * @param maintainCount Whether to maintain a count of IDs for a key once
    * the entry limit has exceeded.
-   * @param env The JE Environemnt
+   * @param env The JE Environment
    * @param entryContainer The database entryContainer holding this index.
    * @throws DatabaseException If an error occurs in the JE database.
    */
@@ -139,6 +145,7 @@
     super(name, env, entryContainer);
     this.indexer = indexer;
     this.comparator = indexer.getComparator();
+    this.bsComparator = indexer.getBSComparator();
     this.indexEntryLimit = indexEntryLimit;
     this.cursorEntryLimit = cursorEntryLimit;
     this.maintainCount = maintainCount;
@@ -191,17 +198,17 @@
    *         count is exceeded. False if it already exists in the entry ID set
    *         for the given key.
    */
-  public boolean insertID(IndexBuffer buffer, byte[] keyBytes,
+  public boolean insertID(IndexBuffer buffer, ByteString keyBytes,
                           EntryID entryID)
   {
-    TreeMap<byte[], IndexBuffer.BufferedIndexValues> bufferedOperations =
+    TreeMap<ByteString, IndexBuffer.BufferedIndexValues> bufferedOperations =
         buffer.getBufferedIndex(this);
     IndexBuffer.BufferedIndexValues values = null;
 
     if(bufferedOperations == null)
     {
-      bufferedOperations = new TreeMap<byte[],
-          IndexBuffer.BufferedIndexValues>(comparator);
+      bufferedOperations =
+          new TreeMap<ByteString, IndexBuffer.BufferedIndexValues>(bsComparator);
       buffer.putBufferedIndex(this, bufferedOperations);
     }
     else
@@ -244,10 +251,8 @@
   public boolean insertID(Transaction txn, DatabaseEntry key, EntryID entryID)
        throws DatabaseException
   {
-    OperationStatus status;
     DatabaseEntry entryIDData = entryID.getDatabaseEntry();
     DatabaseEntry data = new DatabaseEntry();
-    boolean success = false;
 
     if(maintainCount)
     {
@@ -262,7 +267,7 @@
     }
     else
     {
-      status = read(txn, key, data, LockMode.READ_COMMITTED);
+      final OperationStatus status = read(txn, key, data, LockMode.READ_COMMITTED);
       if(status == OperationStatus.SUCCESS)
       {
         EntryIDSet entryIDList =
@@ -284,8 +289,7 @@
       {
         if(rebuildRunning || trusted)
         {
-          status = insert(txn, key, entryIDData);
-          if(status == OperationStatus.KEYEXIST)
+          if (insert(txn, key, entryIDData) == OperationStatus.KEYEXIST)
           {
             for(int i = 1; i < phantomWriteRetires; i++)
             {
@@ -303,8 +307,7 @@
         }
       }
     }
-
-    return success;
+    return false;
   }
 
 
@@ -705,17 +708,17 @@
    *         count is exceeded. False if it already exists in the entry ID set
    *         for the given key.
    */
-  public boolean removeID(IndexBuffer buffer, byte[] keyBytes,
+  public boolean removeID(IndexBuffer buffer, ByteString keyBytes,
                           EntryID entryID)
   {
-    TreeMap<byte[], IndexBuffer.BufferedIndexValues> bufferedOperations =
+    TreeMap<ByteString, IndexBuffer.BufferedIndexValues> bufferedOperations =
         buffer.getBufferedIndex(this);
     IndexBuffer.BufferedIndexValues values = null;
 
     if(bufferedOperations == null)
     {
-      bufferedOperations = new TreeMap<byte[],
-          IndexBuffer.BufferedIndexValues>(comparator);
+      bufferedOperations =
+          new TreeMap<ByteString, IndexBuffer.BufferedIndexValues>(bsComparator);
       buffer.putBufferedIndex(this, bufferedOperations);
     }
     else
@@ -878,16 +881,16 @@
    * @param buffer The index buffer to use to store the deleted keys
    * @param keyBytes The index key bytes.
    */
-  public void delete(IndexBuffer buffer, byte[] keyBytes)
+  public void delete(IndexBuffer buffer, ByteString keyBytes)
   {
-    TreeMap<byte[], IndexBuffer.BufferedIndexValues> bufferedOperations =
+    TreeMap<ByteString, IndexBuffer.BufferedIndexValues> bufferedOperations =
         buffer.getBufferedIndex(this);
     IndexBuffer.BufferedIndexValues values = null;
 
     if(bufferedOperations == null)
     {
-      bufferedOperations = new TreeMap<byte[],
-          IndexBuffer.BufferedIndexValues>(comparator);
+      bufferedOperations =
+          new TreeMap<ByteString, IndexBuffer.BufferedIndexValues>(bsComparator);
       buffer.putBufferedIndex(this, bufferedOperations);
     }
     else
@@ -1182,19 +1185,17 @@
   public boolean addEntry(IndexBuffer buffer, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException
   {
-    HashSet<byte[]> addKeys = new HashSet<byte[]>();
-    boolean success = true;
-
+    HashSet<ByteString> addKeys = new HashSet<ByteString>();
     indexer.indexEntry(entry, addKeys);
 
-    for (byte[] keyBytes : addKeys)
+    boolean success = true;
+    for (ByteString keyBytes : addKeys)
     {
       if(!insertID(buffer, keyBytes, entryID))
       {
         success = false;
       }
     }
-
     return success;
   }
 
@@ -1212,21 +1213,20 @@
   public boolean addEntry(Transaction txn, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException
   {
-    TreeSet<byte[]> addKeys = new TreeSet<byte[]>(indexer.getComparator());
-    boolean success = true;
-
+    TreeSet<ByteString> addKeys =
+        new TreeSet<ByteString>(indexer.getBSComparator());
     indexer.indexEntry(entry, addKeys);
 
     DatabaseEntry key = new DatabaseEntry();
-    for (byte[] keyBytes : addKeys)
+    boolean success = true;
+    for (ByteString keyBytes : addKeys)
     {
-      key.setData(keyBytes);
+      key.setData(keyBytes.toByteArray());
       if(!insertID(txn, key, entryID))
       {
         success = false;
       }
     }
-
     return success;
   }
 
@@ -1242,11 +1242,10 @@
   public void removeEntry(IndexBuffer buffer, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException
   {
-    HashSet<byte[]> delKeys = new HashSet<byte[]>();
-
+    HashSet<ByteString> delKeys = new HashSet<ByteString>();
     indexer.indexEntry(entry, delKeys);
 
-    for (byte[] keyBytes : delKeys)
+    for (ByteString keyBytes : delKeys)
     {
       removeID(buffer, keyBytes, entryID);
     }
@@ -1264,14 +1263,14 @@
   public void removeEntry(Transaction txn, EntryID entryID, Entry entry)
        throws DatabaseException, DirectoryException
   {
-    TreeSet<byte[]> delKeys = new TreeSet<byte[]>(indexer.getComparator());
-
+    TreeSet<ByteString> delKeys =
+        new TreeSet<ByteString>(indexer.getBSComparator());
     indexer.indexEntry(entry, delKeys);
 
     DatabaseEntry key = new DatabaseEntry();
-    for (byte[] keyBytes : delKeys)
+    for (ByteString keyBytes : delKeys)
     {
-      key.setData(keyBytes);
+      key.setData(keyBytes.toByteArray());
       removeID(txn, key, entryID);
     }
   }
@@ -1295,15 +1294,14 @@
                           List<Modification> mods)
        throws DatabaseException
   {
-    TreeMap<byte[], Boolean> modifiedKeys =
-        new TreeMap<byte[], Boolean>(indexer.getComparator());
-
+    TreeMap<ByteString, Boolean> modifiedKeys =
+        new TreeMap<ByteString, Boolean>(indexer.getBSComparator());
     indexer.modifyEntry(oldEntry, newEntry, mods, modifiedKeys);
 
     DatabaseEntry key = new DatabaseEntry();
-    for (Map.Entry<byte[], Boolean> modifiedKey : modifiedKeys.entrySet())
+    for (Map.Entry<ByteString, Boolean> modifiedKey : modifiedKeys.entrySet())
     {
-      key.setData(modifiedKey.getKey());
+      key.setData(modifiedKey.getKey().toByteArray());
       if(modifiedKey.getValue())
       {
         insertID(txn, key, entryID);
@@ -1333,11 +1331,11 @@
                           List<Modification> mods)
       throws DatabaseException
   {
-    TreeMap<byte[], Boolean> modifiedKeys =
-      new TreeMap<byte[], Boolean>(indexer.getComparator());
-
+    TreeMap<ByteString, Boolean> modifiedKeys =
+        new TreeMap<ByteString, Boolean>(indexer.getBSComparator());
     indexer.modifyEntry(oldEntry, newEntry, mods, modifiedKeys);
-    for (Map.Entry<byte[], Boolean> modifiedKey : modifiedKeys.entrySet())
+
+    for (Map.Entry<ByteString, Boolean> modifiedKey : modifiedKeys.entrySet())
     {
       if(modifiedKey.getValue())
       {
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexBuffer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexBuffer.java
index 3930130..f26a909 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexBuffer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/IndexBuffer.java
@@ -22,17 +22,19 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
-import com.sleepycat.je.Transaction;
-import com.sleepycat.je.DatabaseException;
-import com.sleepycat.je.DatabaseEntry;
-
 import java.util.*;
 
+import org.forgerock.opendj.ldap.ByteString;
 import org.opends.server.types.DirectoryException;
 
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.DatabaseException;
+import com.sleepycat.je.Transaction;
+
 /**
  * A buffered index is used to buffer multiple reads or writes to the
  * same index key into a single read or write.
@@ -48,8 +50,7 @@
    * The buffered records stored as a map from the record key to the
    * buffered value for that key for each index.
    */
-  private LinkedHashMap<Index,
-      TreeMap<byte[], BufferedIndexValues>> bufferedIndexes;
+  private LinkedHashMap<Index, TreeMap<ByteString, BufferedIndexValues>> bufferedIndexes;
 
   /**
    * The buffered records stored as a set of buffered VLV values
@@ -60,7 +61,8 @@
   /**
    * A simple class representing a pair of added and deleted indexed IDs.
    */
-  public static class BufferedIndexValues {
+  static class BufferedIndexValues
+  {
     EntryIDSet addedIDs;
     EntryIDSet deletedIDs;
   }
@@ -68,7 +70,8 @@
   /**
    * A simple class representing a pair of added and deleted VLV values.
    */
-  public static class BufferedVLVValues {
+  static class BufferedVLVValues
+  {
     TreeSet<SortValues> addedValues;
     TreeSet<SortValues> deletedValues;
   }
@@ -82,7 +85,7 @@
   public IndexBuffer(EntryContainer entryContainer)
   {
     bufferedIndexes =
-        new LinkedHashMap<Index, TreeMap<byte[], BufferedIndexValues>>();
+        new LinkedHashMap<Index, TreeMap<ByteString, BufferedIndexValues>>();
     bufferedVLVIndexes = new LinkedHashMap<VLVIndex, BufferedVLVValues>();
     this.entryContainer = entryContainer;
   }
@@ -94,7 +97,7 @@
    * @return The buffered values or <code>null</code> if there are
    * no buffered values for the specified index.
    */
-  public TreeMap<byte[], BufferedIndexValues> getBufferedIndex(Index index)
+  public TreeMap<ByteString, BufferedIndexValues> getBufferedIndex(Index index)
   {
     return bufferedIndexes.get(index);
   }
@@ -105,8 +108,8 @@
    * @param index The index affected by the buffered values.
    * @param bufferedValues The buffered values for the index.
    */
-  public void putBufferedIndex(Index index, TreeMap<byte[],
-      BufferedIndexValues> bufferedValues)
+  public void putBufferedIndex(Index index,
+      TreeMap<ByteString, BufferedIndexValues> bufferedValues)
   {
     bufferedIndexes.put(index, bufferedValues);
   }
@@ -146,9 +149,6 @@
   public void flush(Transaction txn)
       throws DatabaseException, DirectoryException
   {
-    TreeMap<byte[], BufferedIndexValues> bufferedValues;
-    BufferedVLVValues bufferedVLVValues;
-    byte[] keyBytes;
     DatabaseEntry key = new DatabaseEntry();
 
     for(AttributeIndex attributeIndex :
@@ -156,18 +156,18 @@
     {
       for(Index index : attributeIndex.getAllIndexes())
       {
-        bufferedValues = bufferedIndexes.remove(index);
+        TreeMap<ByteString, BufferedIndexValues> bufferedValues =
+            bufferedIndexes.remove(index);
 
         if(bufferedValues != null)
         {
-          Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+          Iterator<Map.Entry<ByteString, BufferedIndexValues>> keyIterator =
               bufferedValues.entrySet().iterator();
           while(keyIterator.hasNext())
           {
-            Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+            Map.Entry<ByteString, BufferedIndexValues> bufferedKey =
                 keyIterator.next();
-            keyBytes = bufferedKey.getKey();
-            key.setData(keyBytes);
+            key.setData(bufferedKey.getKey().toByteArray());
 
             index.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
                 bufferedKey.getValue().addedIDs);
@@ -180,8 +180,7 @@
 
     for(VLVIndex vlvIndex : entryContainer.getVLVIndexes())
     {
-      bufferedVLVValues = bufferedVLVIndexes.remove(vlvIndex);
-
+      BufferedVLVValues bufferedVLVValues = bufferedVLVIndexes.remove(vlvIndex);
       if(bufferedVLVValues != null)
       {
         vlvIndex.updateIndex(txn, bufferedVLVValues.addedValues,
@@ -190,18 +189,18 @@
     }
 
     Index id2children = entryContainer.getID2Children();
-    bufferedValues = bufferedIndexes.remove(id2children);
+    TreeMap<ByteString, BufferedIndexValues> bufferedValues =
+        bufferedIndexes.remove(id2children);
 
     if(bufferedValues != null)
     {
-      Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+      Iterator<Map.Entry<ByteString, BufferedIndexValues>> keyIterator =
           bufferedValues.entrySet().iterator();
       while(keyIterator.hasNext())
       {
-        Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+        Map.Entry<ByteString, BufferedIndexValues> bufferedKey =
             keyIterator.next();
-        keyBytes = bufferedKey.getKey();
-        key.setData(keyBytes);
+        key.setData(bufferedKey.getKey().toByteArray());
 
         id2children.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
             bufferedKey.getValue().addedIDs);
@@ -215,14 +214,13 @@
 
     if(bufferedValues != null)
     {
-      Iterator<Map.Entry<byte[], BufferedIndexValues>> keyIterator =
+      Iterator<Map.Entry<ByteString, BufferedIndexValues>> keyIterator =
           bufferedValues.entrySet().iterator();
       while(keyIterator.hasNext())
       {
-        Map.Entry<byte[], BufferedIndexValues> bufferedKey =
+        Map.Entry<ByteString, BufferedIndexValues> bufferedKey =
             keyIterator.next();
-        keyBytes = bufferedKey.getKey();
-        key.setData(keyBytes);
+        key.setData(bufferedKey.getKey().toByteArray());
 
         id2subtree.updateKey(txn, key, bufferedKey.getValue().deletedIDs,
             bufferedKey.getValue().addedIDs);
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Indexer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Indexer.java
index a876e85..3f51f03 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Indexer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/Indexer.java
@@ -22,17 +22,20 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
- *      Portions copyright 2012 ForgeRock AS.
+ *      Portions copyright 2012-2014 ForgeRock AS.
  */
 package org.opends.server.backends.jeb;
 
-import org.opends.server.types.Entry;
-import org.opends.server.types.Modification;
-
 import java.util.Comparator;
-import java.util.Set;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+
+import org.forgerock.opendj.ldap.ByteString;
+import org.opends.server.backends.jeb.AttributeIndex.BSKeyComparator;
+import org.opends.server.backends.jeb.AttributeIndex.KeyComparator;
+import org.opends.server.types.Entry;
+import org.opends.server.types.Modification;
 
 /**
  * This class attempts to abstract the generation and comparison of keys
@@ -41,12 +44,32 @@
 public abstract class Indexer
 {
   /**
-   * Get the comparator that must be used to compare index keys
-   * generated by this class.
+   * The comparator for keys generated by this class.
+   */
+  private static final KeyComparator comparator = new KeyComparator();
+  private static final BSKeyComparator bsComparator = new BSKeyComparator();
+
+  /**
+   * Get the comparator that must be used to compare index keys generated by
+   * this class.
    *
    * @return A byte array comparator.
    */
-  public abstract Comparator<byte[]> getComparator();
+  public final Comparator<byte[]> getComparator()
+  {
+    return comparator;
+  }
+
+  /**
+   * Get the comparator that must be used to compare index keys generated by
+   * this class.
+   *
+   * @return A byte string comparator.
+   */
+  public final Comparator<ByteString> getBSComparator()
+  {
+    return bsComparator;
+  }
 
   /**
    * Generate the set of index keys for an entry.
@@ -54,7 +77,7 @@
    * @param entry The entry.
    * @param keys The set into which the generated keys will be inserted.
    */
-  public abstract void indexEntry(Entry entry, Set<byte[]> keys);
+  public abstract void indexEntry(Entry entry, Set<ByteString> keys);
 
   /**
    * Generate the set of index keys to be added and the set of index keys
@@ -65,7 +88,7 @@
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
   public abstract void replaceEntry(Entry oldEntry, Entry newEntry,
-                                    Map<byte[], Boolean> modifiedKeys);
+                                    Map<ByteString, Boolean> modifiedKeys);
 
   /**
    * Generate the set of index keys to be added and the set of index keys
@@ -78,5 +101,6 @@
    */
   public abstract void modifyEntry(Entry oldEntry, Entry newEntry,
                                    List<Modification> mods,
-                                   Map<byte[], Boolean> modifiedKeys);
+                                   Map<ByteString, Boolean> modifiedKeys);
+
 }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java
index a3e213f..2b49215 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/JEExtensibleIndexer.java
@@ -26,12 +26,10 @@
  */
 package org.opends.server.backends.jeb;
 
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.TreeSet;
 
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.ldap.ByteString;
@@ -52,14 +50,6 @@
   private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
 
   /**
-   * The comparator for index keys generated by this class.
-   */
-  private static final Comparator<byte[]> comparator =
-       new AttributeIndex.KeyComparator();
-
-
-
-  /**
    * The attribute type for which this instance will
    * generate index keys.
    */
@@ -104,26 +94,11 @@
   }
 
 
-
-  /**
-   * Gets the comparator that must be used to compare index keys
-   * generated by this class.
-   *
-   * @return A byte array comparator.
-   */
-  @Override
-  public Comparator<byte[]> getComparator()
-  {
-    return comparator;
-  }
-
-
-
   /**
    * {@inheritDoc}
    */
   @Override
-  public void indexEntry(Entry entry, Set<byte[]> keys)
+  public void indexEntry(Entry entry, Set<ByteString> keys)
   {
     List<Attribute> attrList =
          entry.getAttribute(attributeType);
@@ -140,7 +115,7 @@
    */
   @Override
   public void replaceEntry(Entry oldEntry, Entry newEntry,
-                           Map<byte[], Boolean> modifiedKeys)
+                           Map<ByteString, Boolean> modifiedKeys)
   {
     List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
     List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
@@ -158,7 +133,7 @@
   @Override
   public void modifyEntry(Entry oldEntry, Entry newEntry,
                           List<Modification> mods,
-                          Map<byte[], Boolean> modifiedKeys)
+                          Map<ByteString, Boolean> modifiedKeys)
   {
     List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
     List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
@@ -175,11 +150,10 @@
    * @param keys The set into which the generated keys will be inserted.
    */
   private void indexAttribute(List<Attribute> attrList,
-                              Set<byte[]> keys)
+                              Set<ByteString> keys)
   {
     if (attrList == null) return;
 
-    Set<ByteString> keysBS = new TreeSet<ByteString>();
     for (Attribute attr : attrList)
     {
       if (!attr.isVirtual())
@@ -188,7 +162,7 @@
         {
           try
           {
-            extensibleIndexer.createKeys(null, value.getValue(), null, keysBS);
+            extensibleIndexer.createKeys(null, value.getValue(), null, keys);
           }
           catch (DecodeException e)
           {
@@ -197,10 +171,6 @@
         }
       }
     }
-    for (ByteString key : keysBS)
-    {
-      keys.add(key.toByteArray());
-    }
   }
 
 
@@ -214,12 +184,12 @@
    * be inserted or <code>false</code> otherwise.
    */
   private void indexAttribute(List<Attribute> attrList,
-                              Map<byte[], Boolean> modifiedKeys,
+                              Map<ByteString, Boolean> modifiedKeys,
                               Boolean insert)
   {
     if (attrList == null) return;
 
-    final Set<byte[]> keys = new HashSet<byte[]>();
+    final Set<ByteString> keys = new HashSet<ByteString>();
     indexAttribute(attrList, keys);
     computeModifiedKeys(modifiedKeys, insert, keys);
   }
@@ -238,10 +208,10 @@
    * @param keys
    *          The index keys to map.
    */
-  private static void computeModifiedKeys(Map<byte[], Boolean> modifiedKeys,
-      Boolean insert, final Set<byte[]> keys)
+  private static void computeModifiedKeys(Map<ByteString, Boolean> modifiedKeys,
+      Boolean insert, Set<ByteString> keys)
   {
-    for (byte[] key : keys)
+    for (ByteString key : keys)
     {
       Boolean cInsert = modifiedKeys.get(key);
       if (cInsert == null)
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/NullIndex.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/NullIndex.java
index e7a42a0..8d68805 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/NullIndex.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/NullIndex.java
@@ -27,6 +27,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
 import org.opends.server.backends.jeb.importLDIF.ImportIDSet;
 import org.opends.server.types.DirectoryException;
@@ -53,7 +54,7 @@
    * @param state
    *          The state database to persist index state info.
    * @param env
-   *          The JE Environemnt
+   *          The JE Environment
    * @param entryContainer
    *          The database entryContainer holding this index.
    * @throws DatabaseException
@@ -69,7 +70,8 @@
 
   /** {@inheritDoc} */
   @Override
-  public boolean insertID(IndexBuffer buffer, byte[] keyBytes, EntryID entryID)
+  public boolean insertID(IndexBuffer buffer, ByteString keyBytes,
+      EntryID entryID)
   {
     return true;
   }
@@ -129,7 +131,8 @@
 
   /** {@inheritDoc} */
   @Override
-  public boolean removeID(IndexBuffer buffer, byte[] keyBytes, EntryID entryID)
+  public boolean removeID(IndexBuffer buffer, ByteString keyBytes,
+      EntryID entryID)
   {
     return true;
   }
@@ -158,7 +161,7 @@
 
   /** {@inheritDoc} */
   @Override
-  public void delete(IndexBuffer buffer, byte[] keyBytes)
+  public void delete(IndexBuffer buffer, ByteString keyBytes)
   {
     // Do nothing.
   }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/PresenceIndexer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/PresenceIndexer.java
index 58fac44..ab510e5 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/PresenceIndexer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/PresenceIndexer.java
@@ -22,18 +22,19 @@
  *
  *
  *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Portions Copyright 2014 ForgeRock AS
  */
 package org.opends.server.backends.jeb;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.forgerock.opendj.ldap.ByteString;
 import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
 import org.opends.server.types.Entry;
 import org.opends.server.types.Modification;
-import org.opends.server.types.AttributeType;
-
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.Map;
 
 /**
  * An implementation of an Indexer for attribute presence.
@@ -41,13 +42,6 @@
 public class PresenceIndexer extends Indexer
 {
 
-
-  /**
-   * The comparator for index keys generated by this class.
-   */
-  private static final Comparator<byte[]> comparator =
-       new AttributeIndex.KeyComparator();
-
   /**
    * The attribute type for which this instance will
    * generate index keys.
@@ -68,31 +62,20 @@
    * Get a string representation of this object.
    * @return A string representation of this object.
    */
+  @Override
   public String toString()
   {
     return attributeType.getNameOrOID() + ".presence";
   }
 
   /**
-   * Get the comparator that must be used to compare index keys
-   * generated by this class.
-   *
-   * @return A byte array comparator.
-   */
-  public Comparator<byte[]> getComparator()
-  {
-    return comparator;
-  }
-
-
-
-  /**
    * Generate the set of index keys for an entry.
    *
    * @param entry The entry.
    * @param keys The set into which the generated keys will be inserted.
    */
-  public void indexEntry(Entry entry,  Set<byte[]> keys)
+  @Override
+  public void indexEntry(Entry entry, Set<ByteString> keys)
   {
     List<Attribute> attrList =
          entry.getAttribute(attributeType);
@@ -100,7 +83,7 @@
     {
       if (!attrList.isEmpty())
       {
-        keys.add(AttributeIndex.presenceKey.getData());
+        keys.add(getPresenceKeyData());
       }
     }
   }
@@ -115,8 +98,9 @@
    * @param newEntry The new entry contents.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void replaceEntry(Entry oldEntry, Entry newEntry,
-                           Map<byte[], Boolean> modifiedKeys)
+                           Map<ByteString, Boolean> modifiedKeys)
   {
     List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
     List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
@@ -124,14 +108,14 @@
     {
       if(newAttributes != null)
       {
-        modifiedKeys.put(AttributeIndex.presenceKey.getData(), true);
+        modifiedKeys.put(getPresenceKeyData(), true);
       }
     }
     else
     {
       if(newAttributes == null)
       {
-        modifiedKeys.put(AttributeIndex.presenceKey.getData(), false);
+        modifiedKeys.put(getPresenceKeyData(), false);
       }
     }
   }
@@ -147,9 +131,10 @@
    * @param mods The set of modifications that were applied to the entry.
    * @param modifiedKeys The map into which the modified keys will be inserted.
    */
+  @Override
   public void modifyEntry(Entry oldEntry, Entry newEntry,
                           List<Modification> mods,
-                          Map<byte[], Boolean> modifiedKeys)
+                          Map<ByteString, Boolean> modifiedKeys)
   {
     List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true);
     List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true);
@@ -157,15 +142,20 @@
     {
       if(newAttributes != null)
       {
-        modifiedKeys.put(AttributeIndex.presenceKey.getData(), true);
+        modifiedKeys.put(getPresenceKeyData(), true);
       }
     }
     else
     {
       if(newAttributes == null)
       {
-        modifiedKeys.put(AttributeIndex.presenceKey.getData(), false);
+        modifiedKeys.put(getPresenceKeyData(), false);
       }
     }
   }
+
+  private ByteString getPresenceKeyData()
+  {
+    return ByteString.wrap(AttributeIndex.presenceKey.getData());
+  }
 }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/VerifyJob.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/VerifyJob.java
index cace05a..e1ae00d 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/VerifyJob.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/VerifyJob.java
@@ -1116,7 +1116,7 @@
 
         if (entryIDList.isDefined())
         {
-          final byte[] value = key.getData();
+          final ByteString value = ByteString.wrap(key.getData());
           EntryID prevID = null;
 
           for (EntryID id : entryIDList)
@@ -1163,13 +1163,13 @@
             // require referenced external variables to be final.
             final AtomicBoolean foundMatchingKey = new AtomicBoolean(false);
 
-            Set<byte[]> dummySet = new AbstractSet<byte[]>()
+            Set<ByteString> dummySet = new AbstractSet<ByteString>()
             {
               @Override
-              public Iterator<byte[]> iterator()
+              public Iterator<ByteString> iterator()
               {
                 // The set is always empty.
-                return Collections.<byte[]>emptySet().iterator();
+                return Collections.<ByteString> emptySet().iterator();
               }
 
               @Override
@@ -1180,9 +1180,10 @@
               }
 
               @Override
-              public boolean add(byte[] e)
+              public boolean add(ByteString e)
               {
-                if (Arrays.equals(e, value)) {
+                if (value.equals(e))
+                {
                   // We could terminate processing at this point by throwing an
                   // UnsupportedOperationException, but this optimization is
                   // already ugly enough.
@@ -1203,7 +1204,7 @@
                 logger.trace("Reference to entry "
                     + "<%s> which does not match the value%n%s",
                     entry.getName(),
-                    keyDump(index, value));
+                    keyDump(index, value.toByteArray()));
               }
             }
           }
@@ -1626,6 +1627,7 @@
       verifyAttributeInIndex(presenceIndex, txn, presenceKey, entryID);
     }
 
+    final DatabaseEntry key = new DatabaseEntry();
     for (Attribute attr : attrList)
     {
       final AttributeType attrType = attr.getAttributeType();
@@ -1637,17 +1639,13 @@
 
         if (equalityIndex != null)
         {
-          // TODO JNR reuse DatabaseEntry object for all indexes?
-          DatabaseEntry key = new DatabaseEntry(normalizedBytes);
+          key.setData(normalizedBytes);
           verifyAttributeInIndex(equalityIndex, txn, key, entryID);
         }
 
         if (substringIndex != null)
         {
-          Set<ByteString> keyBytesSet =
-              attrIndex.substringKeys(normalizedBytes);
-          DatabaseEntry key = new DatabaseEntry();
-          for (ByteString keyBytes : keyBytesSet)
+          for (ByteString keyBytes : attrIndex.substringKeys(normalizedBytes))
           {
             key.setData(keyBytes.toByteArray());
             verifyAttributeInIndex(substringIndex, txn, key, entryID);
@@ -1656,15 +1654,13 @@
 
         if (orderingIndex != null)
         {
-          normalizedBytes = normalize(attrType.getOrderingMatchingRule(), bsValue);
-          DatabaseEntry key = new DatabaseEntry(normalizedBytes);
+          key.setData(normalize(attrType.getOrderingMatchingRule(), bsValue));
           verifyAttributeInIndex(orderingIndex, txn, key, entryID);
         }
 
         if (approximateIndex != null)
         {
-          normalizedBytes = normalize(attrType.getApproximateMatchingRule(), bsValue);
-          DatabaseEntry key = new DatabaseEntry(normalizedBytes);
+          key.setData(normalize(attrType.getApproximateMatchingRule(), bsValue));
           verifyAttributeInIndex(approximateIndex, txn, key, entryID);
         }
       }
diff --git a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
index c2a21e5..beec8b1 100644
--- a/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
+++ b/opendj3-server-dev/src/server/org/opends/server/backends/jeb/importLDIF/Importer.java
@@ -36,6 +36,7 @@
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.ResultCode;
 import org.forgerock.util.Utils;
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn.IndexType;
@@ -48,7 +49,6 @@
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.extensions.DiskSpaceMonitor;
 import org.opends.server.types.*;
-import org.forgerock.opendj.ldap.ResultCode;
 import org.opends.server.util.LDIFReader;
 import org.opends.server.util.Platform;
 import org.opends.server.util.StaticUtils;
@@ -1431,8 +1431,8 @@
    */
   private class AppendReplaceTask extends ImportTask
   {
-    private final Set<byte[]> insertKeySet = new HashSet<byte[]>(),
-        deleteKeySet = new HashSet<byte[]>();
+    private final Set<ByteString> insertKeySet = new HashSet<ByteString>();
+    private final Set<ByteString> deleteKeySet = new HashSet<ByteString>();
     private final EntryInformation entryInfo = new EntryInformation();
     private Entry oldEntry;
     private EntryID entryID;
@@ -1536,16 +1536,16 @@
       {
         deleteKeySet.clear();
         index.indexer.indexEntry(oldEntry, deleteKeySet);
-        for (byte[] delKey : deleteKeySet)
+        for (ByteString delKey : deleteKeySet)
         {
-          processKey(index, delKey, entryID, indexComparator, indexKey, false);
+          processKey(index, delKey.toByteArray(), entryID, indexComparator, indexKey, false);
         }
       }
       insertKeySet.clear();
       index.indexer.indexEntry(entry, insertKeySet);
-      for (byte[] key : insertKeySet)
+      for (ByteString key : insertKeySet)
       {
-        processKey(index, key, entryID, indexComparator, indexKey, true);
+        processKey(index, key.toByteArray(), entryID, indexComparator, indexKey, true);
       }
     }
   }
@@ -1558,7 +1558,7 @@
   {
     private final Map<IndexKey, IndexOutputBuffer> indexBufferMap =
         new HashMap<IndexKey, IndexOutputBuffer>();
-    private final Set<byte[]> insertKeySet = new HashSet<byte[]>();
+    private final Set<ByteString> insertKeySet = new HashSet<ByteString>();
     private final EntryInformation entryInfo = new EntryInformation();
     private DatabaseEntry keyEntry = new DatabaseEntry(),
         valEntry = new DatabaseEntry();
@@ -1745,9 +1745,9 @@
     {
       insertKeySet.clear();
       index.indexer.indexEntry(entry, insertKeySet);
-      for (byte[] key : insertKeySet)
+      for (ByteString key : insertKeySet)
       {
-        processKey(index, key, entryID, indexComparator, indexKey, true);
+        processKey(index, key.toByteArray(), entryID, indexComparator, indexKey, true);
       }
     }
 
diff --git a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
index 8b88953..95f9bce 100644
--- a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
+++ b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestBackendImpl.java
@@ -28,6 +28,7 @@
 
 import java.util.*;
 
+import org.forgerock.opendj.ldap.ByteString;
 import org.forgerock.opendj.ldap.ConditionResult;
 import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
 import org.forgerock.opendj.ldap.ResultCode;
@@ -47,6 +48,12 @@
 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;
@@ -887,13 +894,13 @@
   private void assertIndexContainsID(Indexer indexer, Entry entry, Index index,
       EntryID entryID)
   {
-    Set<byte[]> addKeys = new HashSet<byte[]>();
+    Set<ByteString> addKeys = new HashSet<ByteString>();
     indexer.indexEntry(entry, addKeys);
 
     DatabaseEntry key = new DatabaseEntry();
-    for (byte[] keyBytes : addKeys)
+    for (ByteString keyBytes : addKeys)
     {
-      key.setData(keyBytes);
+      key.setData(keyBytes.toByteArray());
       assertEquals(index.containsID(null, key, entryID), TRUE);
     }
   }
@@ -901,20 +908,21 @@
   private void assertIndexContainsID(Indexer indexer, Entry entry,
       Index index, EntryID entryID, ConditionResult expected)
   {
-    Set<byte[]> addKeys = new HashSet<byte[]>();
+    Set<ByteString> addKeys = new HashSet<ByteString>();
     indexer.indexEntry(entry, addKeys);
 
     assertIndexContainsID(addKeys, index, entryID, expected);
   }
 
-  private void assertIndexContainsID(Set<byte[]> addKeys, Index index,
+  private void assertIndexContainsID(Set<ByteString> addKeys, Index index,
       EntryID entryID, ConditionResult expected)
   {
     DatabaseEntry key = new DatabaseEntry();
-    for (byte[] keyBytes : addKeys) {
-      key.setData(keyBytes);
+    for (ByteString keyBytes : addKeys)
+    {
+      key.setData(keyBytes.toByteArray());
+      assertEquals(index.containsID(null, key, entryID), expected);
     }
-    assertEquals(index.containsID(null, key, entryID), expected);
   }
 
   @Test(dependsOnMethods = {"testSearchNotIndexed", "testAdd",
@@ -987,7 +995,7 @@
     AttributeType attribute;
     AttributeIndex titleIndex;
     AttributeIndex nameIndex;
-    Set<byte[]> addKeys;
+    Set<ByteString> addKeys;
     Indexer presenceIndexer;
     Indexer equalityIndexer;
     Indexer substringIndexer;
@@ -1039,15 +1047,14 @@
       attribute = DirectoryServer.getAttributeType("name");
       nameIndex = ec.getAttributeIndex(attribute);
 
-      // This current entry in the DB shouldn't be in the presence
-      // titleIndex.
-      addKeys = new HashSet<byte[]>();
-      addKeys.add(AttributeIndex.presenceKey.getData());
+      // This current entry in the DB shouldn't be in the presence titleIndex.
+      addKeys = new HashSet<ByteString>();
+      addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
       assertIndexContainsID(addKeys, titleIndex.presenceIndex, entryID, FALSE);
 
       // This current entry should be in the presence nameIndex.
-      addKeys = new HashSet<byte[]>();
-      addKeys.add(AttributeIndex.presenceKey.getData());
+      addKeys = new HashSet<ByteString>();
+      addKeys.add(ByteString.wrap(AttributeIndex.presenceKey.getData()));
       assertIndexContainsID(addKeys, nameIndex.presenceIndex, entryID, TRUE);
 
       List<Control> noControls = new ArrayList<Control>(0);
diff --git a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
index d09eeb8..0c64162 100644
--- a/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
+++ b/opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
@@ -26,26 +26,27 @@
  */
 package org.opends.server.backends.jeb;
 
-import org.opends.server.core.DirectoryServer;
-import org.opends.server.TestCaseUtils;
-import org.opends.server.types.*;
-import org.forgerock.opendj.ldap.ByteString;
-import org.opends.server.util.StaticUtils;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
 
-import static org.opends.server.util.ServerConstants.OC_TOP;
-import static org.opends.server.util.ServerConstants.OC_EXTENSIBLE_OBJECT;
-import org.testng.annotations.BeforeClass;
+import org.forgerock.opendj.ldap.ByteString;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.*;
+import org.opends.server.util.StaticUtils;
 import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import static org.testng.Assert.*;
 
 import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.LockMode;
 import com.sleepycat.je.OperationStatus;
 import com.sleepycat.je.Transaction;
-import com.sleepycat.je.LockMode;
 
-import java.util.*;
+import static org.opends.server.util.ServerConstants.*;
+import static org.testng.Assert.*;
 
 public class TestVerifyJob extends JebTestCase
 {
@@ -280,7 +281,7 @@
       idBytes[15] = (byte)1;
       //bad jeb format
       idBytes[23] = (byte) 0x04;
-      idSet=new EntryIDSet(null, idBytes);
+      idSet = newEntryIDSet(idBytes);
       id2child.writeKey(txn, key, idSet);
       performBECleanVerify("id2children", 6);
     }
@@ -290,6 +291,11 @@
     }
   }
 
+  private EntryIDSet newEntryIDSet(byte[] idBytes)
+  {
+    return new EntryIDSet((ByteString) null, idBytes);
+  }
+
   /**
    * Runs clean verify against the id2subtree index after adding
    * various errors in that index file.
@@ -313,17 +319,17 @@
       idBytes[3] = (byte)0xff;
       //non-subordinate
       idBytes[15] = (byte)1;
-      idSet=new EntryIDSet(null, idBytes);
+      idSet = newEntryIDSet(idBytes);
       id2subtree.writeKey(txn, key, idSet);
       //Try to break JebFormat version of key entry
       key=addID2EntryReturnKey(junkDN, 4, true);
       idBytes[3]=(byte) 0x04;
       idBytes[15]=(byte)0x00;
-      EntryIDSet idSet1=new EntryIDSet(null, idBytes);
+      EntryIDSet idSet1 = newEntryIDSet(idBytes);
       id2subtree.writeKey(txn, key, idSet1);
       //put invalid key -- no EntryID matches
       key= new EntryID(45).getDatabaseEntry();
-      idSet=new EntryIDSet(null, idBytes);
+      idSet = newEntryIDSet(idBytes);
       id2subtree.writeKey(txn, key, idSet);
       performBECleanVerify("id2subtree", 7);
     }
@@ -518,7 +524,7 @@
       DatabaseEntry key=addID2EntryReturnKey(noParentDN, 10, false);
       byte[] idBytes=new byte[16];
       idBytes[7]=(byte) 0x0A;
-      EntryIDSet idSet=new EntryIDSet(null, idBytes);
+      EntryIDSet idSet = newEntryIDSet(idBytes);
       id2child.writeKey(txn, key, idSet);
       //Add child entry - don't worry about key
       addID2EntryReturnKey(cDN, 11, false);
@@ -527,7 +533,7 @@
       //add parent key/IDSet with bad IDset id
       byte[] idBytesp=new byte[16];
       idBytesp[7]=(byte) 0xFF;
-      EntryIDSet idSetp=new EntryIDSet(null, idBytesp);
+      EntryIDSet idSetp = newEntryIDSet(idBytesp);
       id2child.writeKey(txn, keyp, idSetp);
       performBECompleteVerify("id2children", 3);
     }

--
Gitblit v1.10.0