mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
16.13.2014 ba6deb90899c025c0bd5e8b2bb169a90daa0e2aa
opendj3-server-dev/src/server/org/opends/server/backends/jeb/SortValuesSet.java
@@ -38,8 +38,7 @@
import com.sleepycat.je.DatabaseException;
/**
 * This class represents a partial sorted set of sorted entries in a VLV
 * index.
 * This class represents a partial sorted set of sorted entries in a VLV index.
 */
public class SortValuesSet
{
@@ -96,7 +95,19 @@
  {}
  /**
   * Add the given entryID and values from this VLV idnex.
   * Add the given entryID and values from these sort values.
   *
   * @param sv The sort values to add.
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws DatabaseException If an error occurs in the JE database.
   */
  void add(SortValues sv) throws DatabaseException, DirectoryException
  {
    add(sv.getEntryID(), sv.getValues(), sv.getTypes());
  }
  /**
   * Add the given entryID and values from this VLV index.
   *
   * @param entryID The entry ID to add.
   * @param values The values to add.
@@ -216,21 +227,17 @@
  }
  /**
   * Remove the given entryID and values from this VLV idnex.
   * Remove the given entryID and values from these sort values.
   *
   * @param entryID The entry ID to remove.
   * @param values The values to remove.
   * @return True if the information was successfully removed or False
   * otherwise.
   * @param sv The sort values to remove.
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws DatabaseException If an error occurs in the JE database.
   */
  public boolean remove(long entryID, ByteString[] values)
      throws DatabaseException, DirectoryException
  void remove(SortValues sv) throws DatabaseException, DirectoryException
  {
    if(entryIDs == null || entryIDs.length == 0)
    {
      return false;
      return;
    }
    if(valuesBytesOffsets == null)
@@ -238,50 +245,45 @@
      updateValuesBytesOffsets();
    }
    int pos = binarySearch(entryID, values);
    int pos = binarySearch(sv.getEntryID(), sv.getValues());
    if(pos < 0)
    {
      // Not found.
      return false;
      return;
    }
    // Found it.
    long[] updatedEntryIDs = new long[entryIDs.length - 1];
    System.arraycopy(entryIDs, 0, updatedEntryIDs, 0, pos);
    System.arraycopy(entryIDs, pos+1, updatedEntryIDs, pos,
                     entryIDs.length-pos-1);
    int valuesLength;
    int valuesPos = valuesBytesOffsets[pos];
    if(pos < valuesBytesOffsets.length - 1)
    {
      valuesLength = valuesBytesOffsets[pos+1] - valuesPos;
    }
    else
    {
      // Found it.
      long[] updatedEntryIDs = new long[entryIDs.length - 1];
      System.arraycopy(entryIDs, 0, updatedEntryIDs, 0, pos);
      System.arraycopy(entryIDs, pos+1, updatedEntryIDs, pos,
                       entryIDs.length-pos-1);
      int valuesLength;
      int valuesPos = valuesBytesOffsets[pos];
      if(pos < valuesBytesOffsets.length - 1)
      {
        valuesLength = valuesBytesOffsets[pos+1] - valuesPos;
      }
      else
      {
        valuesLength = valuesBytes.length - valuesPos;
      }
      byte[] updatedValuesBytes = new byte[valuesBytes.length - valuesLength];
      System.arraycopy(valuesBytes, 0, updatedValuesBytes, 0, valuesPos);
      System.arraycopy(valuesBytes, valuesPos + valuesLength,
                       updatedValuesBytes, valuesPos,
                       valuesBytes.length - valuesPos - valuesLength);
      int[] updatedValuesBytesOffsets = new int[valuesBytesOffsets.length - 1];
      System.arraycopy(valuesBytesOffsets, 0, updatedValuesBytesOffsets,
          0, pos);
      // Update the rest of the offsets one by one - Expensive!
      for(int i = pos + 1; i < valuesBytesOffsets.length; i++)
      {
        updatedValuesBytesOffsets[i-1] =
            valuesBytesOffsets[i] - valuesLength;
      }
      entryIDs = updatedEntryIDs;
      valuesBytes = updatedValuesBytes;
      valuesBytesOffsets = updatedValuesBytesOffsets;
      return true;
      valuesLength = valuesBytes.length - valuesPos;
    }
    byte[] updatedValuesBytes = new byte[valuesBytes.length - valuesLength];
    System.arraycopy(valuesBytes, 0, updatedValuesBytes, 0, valuesPos);
    System.arraycopy(valuesBytes, valuesPos + valuesLength,
                     updatedValuesBytes, valuesPos,
                     valuesBytes.length - valuesPos - valuesLength);
    int[] updatedValuesBytesOffsets = new int[valuesBytesOffsets.length - 1];
    System.arraycopy(valuesBytesOffsets, 0, updatedValuesBytesOffsets, 0, pos);
    // Update the rest of the offsets one by one - Expensive!
    for(int i = pos + 1; i < valuesBytesOffsets.length; i++)
    {
      updatedValuesBytesOffsets[i - 1] = valuesBytesOffsets[i] - valuesLength;
    }
    entryIDs = updatedEntryIDs;
    valuesBytes = updatedValuesBytes;
    valuesBytesOffsets = updatedValuesBytesOffsets;
  }
  /**
opendj3-server-dev/src/server/org/opends/server/backends/jeb/VLVIndex.java
@@ -644,13 +644,13 @@
        // This is the last unbounded set.
        while(av != null)
        {
          sortValuesSet.add(av.getEntryID(), av.getValues(), av.getTypes());
          sortValuesSet.add(av);
          av = moveToNextSortValues(aValues);
        }
        while(dv != null)
        {
          sortValuesSet.remove(dv.getEntryID(), dv.getValues());
          sortValuesSet.remove(dv);
          dv = moveToNextSortValues(dValues);
        }
      }
@@ -660,13 +660,13 @@
        while(av != null && av.compareTo(maxValues) <= 0)
        {
          sortValuesSet.add(av.getEntryID(), av.getValues(), av.getTypes());
          sortValuesSet.add(av);
          av = moveToNextSortValues(aValues);
        }
        while(dv != null && dv.compareTo(maxValues) <= 0)
        {
          sortValuesSet.remove(dv.getEntryID(), dv.getValues());
          sortValuesSet.remove(dv);
          dv = moveToNextSortValues(dValues);
        }
      }
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/EntryContainer.java
@@ -1256,7 +1256,7 @@
  /**
   * Returns the entry corresponding to the provided entryID.
   *
   *
   * @param entryID
   *          the id of the entry to retrieve
   * @return the entry corresponding to the provided entryID
@@ -1323,7 +1323,7 @@
      // The cookie contains the ID of the next entry to be returned.
      try
      {
        begin = new EntryID(pageRequest.getCookie().toLong());
        begin = new EntryID(pageRequest.getCookie());
      }
      catch (Exception e)
      {
@@ -1876,7 +1876,7 @@
    indexRemoveEntry(indexBuffer, entry, leafID);
    // Remove the id2c and id2s records for this entry.
    final ByteString leafIDKeyBytes = ByteString.valueOf(leafID.longValue());
    final ByteString leafIDKeyBytes = leafID.toByteString();
    id2children.delete(indexBuffer, leafIDKeyBytes);
    id2subtree.delete(indexBuffer, leafIDKeyBytes);
@@ -1892,7 +1892,7 @@
        throw new JebException(ERR_JEB_MISSING_DN2ID_RECORD.get(parentDN));
      }
      ByteString parentIDBytes = ByteString.valueOf(parentID.longValue());
      ByteString parentIDBytes = parentID.toByteString();
      // Remove from id2children.
      if (isParent)
      {
@@ -2259,8 +2259,8 @@
                {
                  logger.trace("Move of target entry requires renumbering" + "all entries in the subtree. "
                      + "Old DN: %s " + "New DN: %s " + "Old entry ID: %d " + "New entry ID: %d "
                      + "New Superior ID: %d" + oldApexEntry.getName(), entry.getName(), oldApexID.longValue(),
                      newApexID.longValue(), newSuperiorID.longValue());
                      + "New Superior ID: %d" + oldApexEntry.getName(), entry.getName(), oldApexID,
                      newApexID, newSuperiorID);
                }
              }
            }
@@ -2328,9 +2328,9 @@
                  if (logger.isTraceEnabled())
                  {
                    logger.trace("Move of subordinate entry requires " + "renumbering. " + "Old DN: %s "
                        + "New DN: %s " + "Old entry ID: %d " + "New entry ID: %d", oldEntry.getName(), newDN, oldID
                        .longValue(), newID.longValue());
                    logger.trace("Move of subordinate entry requires renumbering. "
                        + "Old DN: %s New DN: %s Old entry ID: %d New entry ID: %d",
                        oldEntry.getName(), newDN, oldID, newID);
                  }
                }
@@ -2459,7 +2459,7 @@
           dn = getParentWithinBase(dn))
      {
        EntryID parentID = dn2id.get(txn, dn, false);
        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
        ByteString parentIDKeyBytes = parentID.toByteString();
        if(isParent)
        {
          id2children.insertID(buffer, parentIDKeyBytes, newID);
@@ -2504,7 +2504,7 @@
      for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
      {
        EntryID parentID = dn2id.get(txn, dn, false);
        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
        ByteString parentIDKeyBytes = parentID.toByteString();
        if(isParent)
        {
          id2children.removeID(buffer, parentIDKeyBytes, oldID);
@@ -2518,7 +2518,7 @@
    {
      // All the subordinates will be renumbered so we have to rebuild
      // id2c and id2s with the new ID.
      ByteString oldIDKeyBytes = ByteString.valueOf(oldID.longValue());
      ByteString oldIDKeyBytes = oldID.toByteString();
      id2children.delete(buffer, oldIDKeyBytes);
      id2subtree.delete(buffer, oldIDKeyBytes);
@@ -2610,7 +2610,7 @@
      for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
      {
        EntryID parentID = dn2id.get(txn, dn, false);
        ByteString parentIDKeyBytes = ByteString.valueOf(parentID.longValue());
        ByteString parentIDKeyBytes = parentID.toByteString();
        id2subtree.removeID(buffer, parentIDKeyBytes, oldID);
      }
    }
@@ -2619,7 +2619,7 @@
    {
      // All the subordinates will be renumbered so we have to rebuild
      // id2c and id2s with the new ID.
      ByteString oldIDKeyBytes = ByteString.valueOf(oldID.longValue());
      ByteString oldIDKeyBytes = oldID.toByteString();
      id2children.delete(buffer, oldIDKeyBytes);
      id2subtree.delete(buffer, oldIDKeyBytes);
@@ -2758,8 +2758,7 @@
    EntryID entryID = dn2id.get(null, baseDN, false);
    if (entryID != null)
    {
      ByteString key = entryIDToDatabase(entryID.longValue());
      EntryIDSet entryIDSet = id2subtree.readKey(key, null);
      EntryIDSet entryIDSet = id2subtree.readKey(entryID.toByteString(), null);
      long count = entryIDSet.size();
      if(count != Long.MAX_VALUE)
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/JebFormat.java
@@ -169,18 +169,6 @@
  }
  /**
   * Encode an entry ID value to its database representation.
   *
   * @param id The entry ID value to be encoded.
   * @return The encoded database value of the entry ID.
   * @see #entryIDFromDatabase(byte[])
   */
  public static ByteString entryIDToDatabase(long id)
  {
    return ByteString.valueOf(id);
  }
  /**
   * Encode an entry ID set count to its database representation.
   *
   * @param count The entry ID set count to be encoded.
@@ -205,7 +193,6 @@
   *
   * @param entryIDArray An array of entry ID values.
   * @return The encoded database value.
   * @see #entryIDListFromDatabase(byte[])
   */
  public static byte[] entryIDListToDatabase(long[] entryIDArray)
  {
@@ -342,7 +329,6 @@
   * @param prefixRDNs The number of prefix RDNs to remove from the encoded
   *                   representation.
   * @return A ByteString containing the key.
   * @see #dnFromDNKey(byte[], int, int, DN)
   */
  public static ByteString dnToDNKey(DN dn, int prefixRDNs)
  {
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SortValuesSet.java
@@ -36,13 +36,8 @@
import org.opends.server.types.DirectoryException;
import org.opends.server.types.SortKey;
import static org.opends.server.backends.pluggable.JebFormat.*;
/**
 * This class represents a partial sorted set of sorted entries in a VLV
 * index.
 * This class represents a partial sorted set of sorted entries in a VLV index.
 */
public class SortValuesSet
{
@@ -99,6 +94,19 @@
  {}
  /**
   * Add the given entryID and values from these sort values.
   *
   * @param sv The sort values to add.
   * @param types The types of the values to add.
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws DatabaseException If an error occurs in the JE database.
   */
  void add(SortValues sv) throws DirectoryException
  {
    add(sv.getEntryID(), sv.getValues(), sv.getTypes());
  }
  /**
   * Add the given entryID and values from this VLV index.
   *
   * @param entryID The entry ID to add.
@@ -219,21 +227,17 @@
  }
  /**
   * Remove the given entryID and values from this VLV index.
   * Remove the given entryID and values from these sort values.
   *
   * @param entryID The entry ID to remove.
   * @param values The values to remove.
   * @return True if the information was successfully removed or False
   * otherwise.
   * @param sv The sort values to remove.
   * @throws DirectoryException If a Directory Server error occurs.
   * @throws StorageRuntimeException If an error occurs in the JE database.
   */
  public boolean remove(long entryID, ByteString[] values)
      throws StorageRuntimeException, DirectoryException
  void remove(SortValues sv) throws DirectoryException
  {
    if(entryIDs == null || entryIDs.length == 0)
    {
      return false;
      return;
    }
    if(valuesBytesOffsets == null)
@@ -241,50 +245,45 @@
      updateValuesBytesOffsets();
    }
    int pos = binarySearch(entryID, values);
    int pos = binarySearch(sv.getEntryID(), sv.getValues());
    if(pos < 0)
    {
      // Not found.
      return false;
      return;
    }
    // Found it.
    long[] updatedEntryIDs = new long[entryIDs.length - 1];
    System.arraycopy(entryIDs, 0, updatedEntryIDs, 0, pos);
    System.arraycopy(entryIDs, pos + 1, updatedEntryIDs, pos,
                     entryIDs.length - pos - 1);
    int valuesLength;
    int valuesPos = valuesBytesOffsets[pos];
    if (pos < valuesBytesOffsets.length - 1)
    {
      valuesLength = valuesBytesOffsets[pos + 1] - valuesPos;
    }
    else
    {
      // Found it.
      long[] updatedEntryIDs = new long[entryIDs.length - 1];
      System.arraycopy(entryIDs, 0, updatedEntryIDs, 0, pos);
      System.arraycopy(entryIDs, pos+1, updatedEntryIDs, pos,
                       entryIDs.length-pos-1);
      int valuesLength;
      int valuesPos = valuesBytesOffsets[pos];
      if(pos < valuesBytesOffsets.length - 1)
      {
        valuesLength = valuesBytesOffsets[pos+1] - valuesPos;
      }
      else
      {
        valuesLength = valuesBytes.length - valuesPos;
      }
      byte[] updatedValuesBytes = new byte[valuesBytes.length - valuesLength];
      System.arraycopy(valuesBytes, 0, updatedValuesBytes, 0, valuesPos);
      System.arraycopy(valuesBytes, valuesPos + valuesLength,
                       updatedValuesBytes, valuesPos,
                       valuesBytes.length - valuesPos - valuesLength);
      int[] updatedValuesBytesOffsets = new int[valuesBytesOffsets.length - 1];
      System.arraycopy(valuesBytesOffsets, 0, updatedValuesBytesOffsets,
          0, pos);
      // Update the rest of the offsets one by one - Expensive!
      for(int i = pos + 1; i < valuesBytesOffsets.length; i++)
      {
        updatedValuesBytesOffsets[i-1] =
            valuesBytesOffsets[i] - valuesLength;
      }
      entryIDs = updatedEntryIDs;
      valuesBytes = updatedValuesBytes;
      valuesBytesOffsets = updatedValuesBytesOffsets;
      return true;
      valuesLength = valuesBytes.length - valuesPos;
    }
    byte[] updatedValuesBytes = new byte[valuesBytes.length - valuesLength];
    System.arraycopy(valuesBytes, 0, updatedValuesBytes, 0, valuesPos);
    System.arraycopy(valuesBytes, valuesPos + valuesLength,
                     updatedValuesBytes, valuesPos,
                     valuesBytes.length - valuesPos - valuesLength);
    int[] updatedValuesBytesOffsets = new int[valuesBytesOffsets.length - 1];
    System.arraycopy(valuesBytesOffsets, 0, updatedValuesBytesOffsets, 0, pos);
    // Update the rest of the offsets one by one - Expensive!
    for (int i = pos + 1; i < valuesBytesOffsets.length; i++)
    {
      updatedValuesBytesOffsets[i - 1] = valuesBytesOffsets[i] - valuesLength;
    }
    entryIDs = updatedEntryIDs;
    valuesBytes = updatedValuesBytes;
    valuesBytesOffsets = updatedValuesBytesOffsets;
  }
  /**
@@ -537,7 +536,7 @@
    int vBytesPos = valuesBytesOffsets[valuesBytesOffsets.length - 1];
    int vBytesLength = valuesBytes.length - vBytesPos;
    ByteString idBytes = entryIDToDatabase(entryIDs[entryIDs.length - 1]);
    ByteString idBytes = ByteString.valueOf(entryIDs[entryIDs.length - 1]);
    ByteStringBuilder keyBytes = new ByteStringBuilder(vBytesLength + idBytes.length());
    keyBytes.append(valuesBytes, vBytesPos, vBytesLength);
    keyBytes.append(idBytes);
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/SuffixContainer.java
@@ -27,8 +27,6 @@
import java.io.Closeable;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
/**
 * Container for a whole suffix environment which stores all entries from the
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VLVIndex.java
@@ -634,13 +634,13 @@
        // This is the last unbounded set.
        while(av != null)
        {
          sortValuesSet.add(av.getEntryID(), av.getValues(), av.getTypes());
          sortValuesSet.add(av);
          av = moveToNextSortValues(aValues);
        }
        while(dv != null)
        {
          sortValuesSet.remove(dv.getEntryID(), dv.getValues());
          sortValuesSet.remove(dv);
          dv = moveToNextSortValues(dValues);
        }
      }
@@ -650,13 +650,13 @@
        while(av != null && av.compareTo(maxValues) <= 0)
        {
          sortValuesSet.add(av.getEntryID(), av.getValues(), av.getTypes());
          sortValuesSet.add(av);
          av = moveToNextSortValues(aValues);
        }
        while(dv != null && dv.compareTo(maxValues) <= 0)
        {
          sortValuesSet.remove(dv.getEntryID(), dv.getValues());
          sortValuesSet.remove(dv);
          dv = moveToNextSortValues(dValues);
        }
      }
@@ -701,11 +701,6 @@
    return null;
  }
  private ByteString encodeKey(SortValues sv) throws DirectoryException
  {
    return encodeKey(sv.getEntryID(), sv.getValues(), sv.getTypes());
  }
  /**
   * Evaluate a search with sort control using this VLV index.
   *
@@ -1093,6 +1088,18 @@
  }
  /**
   * Encode a VLV database key with the provided sort values.
   *
   * @param sv the sort values to encode
   * @return The encoded bytes.
   * @throws DirectoryException If a Directory Server error occurs.
   */
  ByteString encodeKey(SortValues sv) throws DirectoryException
  {
    return encodeKey(sv.getEntryID(), sv.getValues(), sv.getTypes());
  }
  /**
   * Encode a VLV database key with the given information.
   *
   * @param entryID The entry ID to encode.
opendj3-server-dev/src/server/org/opends/server/backends/pluggable/VerifyJob.java
@@ -773,9 +773,7 @@
            logger.traceException(e);
            logger.trace("File id2subtree has malformed ID list " +
                "for ID %s:%n%s%n", entryID,
 StaticUtils
                .bytesToHex(value));
                "for ID %s:%n%s%n", entryID, StaticUtils.bytesToHex(value));
          }
          continue;
        }
@@ -826,7 +824,7 @@
              if (logger.isTraceEnabled())
              {
                logger.trace("File id2subtree has ID %d referencing " +
 "unknown ID %d%n", entryID, id);
                    "unknown ID %d%n", entryID, id);
              }
              continue;
            }
@@ -838,8 +836,7 @@
              {
                logger.trace("File id2subtree has ID %d with DN <%s> " +
                    "referencing ID %d with non-subordinate DN <%s>%n",
 entryID, entry.getName(), id, subordEntry
                    .getName());
                    entryID, entry.getName(), id, subordEntry.getName());
              }
            }
          }
@@ -950,8 +947,7 @@
          {
            // If this is the last one in a bounded set, make sure it is the
            // same as the database key.
            ByteString encodedKey = vlvIndex.encodeKey(
                values.getEntryID(), values.getValues(), values.getTypes());
            ByteString encodedKey = vlvIndex.encodeKey(values);
            if (!key.equals(encodedKey))
            {
              if(logger.isTraceEnabled())
opendj3-server-dev/tests/unit-tests-testng/src/server/org/opends/server/backends/jeb/TestVerifyJob.java
@@ -411,7 +411,7 @@
      ByteString[] badValues = new ByteString[values.length];
      System.arraycopy(values, 1, badValues, 0, values.length - 1);
      badValues[badValues.length-1] = values[0];
      svs.remove(id, values);
      remove(svs, id, values);
      svs.add(id, badValues, types);
      putSortValuesSet(vlvIndex, svs);
@@ -455,7 +455,7 @@
      DatabaseEntry data= new DatabaseEntry(entryBytes.toByteArray());
      assertEquals(id2entry.put(txn, key, data), OperationStatus.SUCCESS);
      //add entry with ramdom bytes
      // add entry with random bytes
      DatabaseEntry key1= new EntryID(4).getDatabaseEntry();
      byte []eBytes = new byte[459];
      for(int i=0;i<459;i++) {
@@ -703,7 +703,7 @@
      SortValuesSet svs = vlvIndex.getSortValuesSet(null, 0, new ByteString[3], types);
      long id = svs.getEntryIDs()[0];
      Entry entry = eContainer.getID2Entry().get(null, new EntryID(id), LockMode.DEFAULT);
      svs.remove(id, vlvIndex.getSortValues(entry));
      remove(svs, id, vlvIndex.getSortValues(entry));
      // Add an incorrectly ordered values.
      SortValuesSet svs2 = svs.split(2);
@@ -716,7 +716,7 @@
      ByteString[] badValues = new ByteString[values.length];
      System.arraycopy(values, 1, badValues, 0, values.length - 1);
      badValues[badValues.length-1] = values[0];
      svs.remove(id, values);
      remove(svs, id, values);
      svs.add(id, badValues, types);
      putSortValuesSet(vlvIndex, svs);
@@ -729,9 +729,14 @@
    }
  }
  private void remove(SortValuesSet svs, long id, ByteString[] values) throws DirectoryException
  {
    svs.remove(new SortValues(new EntryID(id), values, new SortOrder()));
  }
  /**
   * Put a sort values set in this VLV index.
   *
   *
   * @param txn
   *          The transaction to use when retrieving the set or NULL if it is
   *          not required.