opends/src/server/org/opends/server/backends/jeb/BackendImpl.java
@@ -344,35 +344,23 @@ // Preload the database cache. rootContainer.preload(); // Determine the next entry ID and the total number of entries. EntryID highestID = null; long entryCount = 0; for (EntryContainer ec : rootContainer.getEntryContainers()) try { try { EntryID id = ec.getHighestEntryID(); if (highestID == null || id.compareTo(highestID) > 0) { highestID = id; } entryCount += ec.getEntryCount(); } catch (Exception e) { assert debugException(CLASS_NAME, "initializeBackend", e); String message = getMessage(MSGID_JEB_HIGHEST_ID_FAIL); throw new InitializationException(MSGID_JEB_HIGHEST_ID_FAIL, message, e); } // Log an informational message about the number of entries. int msgID = MSGID_JEB_BACKEND_STARTED; String message = getMessage(msgID, rootContainer.getEntryCount()); logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message, msgID); } EntryID.initialize(highestID); // Log an informational message about the number of entries. int msgID = MSGID_JEB_BACKEND_STARTED; String message = getMessage(msgID, entryCount); logError(ErrorLogCategory.BACKEND, ErrorLogSeverity.NOTICE, message, msgID); catch(DatabaseException databaseException) { assert debugException(CLASS_NAME, "initializeBackend", databaseException); String message = getMessage(MSGID_JEB_GET_ENTRY_COUNT_FAILED, databaseException.getMessage()); throw new InitializationException(MSGID_JEB_GET_ENTRY_COUNT_FAILED, message, databaseException); } // Register this backend as a configurable component. DirectoryServer.registerConfigurableComponent(this); @@ -400,6 +388,7 @@ assert debugEnter(CLASS_NAME, "finalizeBackend"); // Deregister our configurable components. // TODO: configurableEnv is always null and will not be deregistered. if (configurableEnv != null) { DirectoryServer.deregisterConfigurableComponent(configurableEnv); opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -125,6 +125,11 @@ private Backend backend; /** * The root container in which this entryContainer belongs. */ private RootContainer rootContainer; /** * The baseDN this entry container is responsible for. */ private DN baseDN; @@ -194,15 +199,17 @@ * container. It is needed by the Directory Server entry cache * methods. * @param config The configuration of the JE backend. * @param env The JE environment to create this entryContainer in * @param env The JE environment to create this entryContainer in. * @param rootContainer The root container this entry container is in. */ public EntryContainer(DN baseDN, Backend backend, Config config, Environment env) Environment env, RootContainer rootContainer) { this.backend = backend; this.baseDN = baseDN; this.config = config; this.env = env; this.rootContainer = rootContainer; // Instantiate the list of database handles. databases = new ArrayList<Database>(); @@ -493,10 +500,9 @@ * The entryContainer must already be open. * * @return The highest entry ID. * @throws JebException If an error occurs in the JE backend. * @throws DatabaseException If an error occurs in the JE database. */ public EntryID getHighestEntryID() throws JebException, DatabaseException public EntryID getHighestEntryID() throws DatabaseException { EntryID entryID = new EntryID(0); Cursor cursor = id2entry.openCursor(null, null); @@ -1455,7 +1461,7 @@ // First time through, assign the next entryID. if (entryID == null) { entryID = EntryID.assignNext(); entryID = rootContainer.getNextEntryID(); } // Insert into dn2id. @@ -2573,7 +2579,12 @@ DirectoryException, JebException { DN requestedNewSuperiorDN = modifyDNOperation.getNewSuperior(); DN requestedNewSuperiorDN = null; if(modifyDNOperation != null) { requestedNewSuperiorDN = modifyDNOperation.getNewSuperior(); } // Check whether the renamed entry already exists. if (dn2id.get(txn, newApexEntry.getDN()) != null) @@ -2634,7 +2645,7 @@ // renumber every entry that moves. This is even more // expensive since every entry has to be deleted from // and added back into the attribute indexes. newApexID = EntryID.assignNext(); newApexID = rootContainer.getNextEntryID(); } } @@ -2710,7 +2721,7 @@ EntryID newID = oldID; if (!newApexID.equals(oldApexID)) { newID = EntryID.assignNext(); newID = rootContainer.getNextEntryID(); } // Move this entry. @@ -2786,7 +2797,7 @@ dn2uri.replaceEntry(txn, oldEntry, newEntry); // Remove the old ID from id2entry. if (!newID.equals(oldID)) if (!newID.equals(oldID) || modifyDNOperation == null) { id2entry.remove(txn, oldID); @@ -2866,10 +2877,11 @@ * @param newEntry The new contents of the target entry. * @throws DirectoryException If a Directory Server error occurs. * @throws DatabaseException If an error occurs in the JE database. * @throws JebException if an error occurs in the JE database. */ private void renameApexEntry(Transaction txn, EntryID entryID, Entry oldEntry, Entry newEntry) throws DirectoryException, DatabaseException throws DirectoryException, DatabaseException, JebException { DN oldDN = oldEntry.getDN(); DN newDN = newEntry.getDN(); @@ -2892,9 +2904,20 @@ // Replace the entry in id2entry. id2entry.put(txn, entryID, newEntry); // Update indexes only for those attributes that changed. indexModifications(txn, oldEntry, newEntry, entryID, modifyDNOperation.getModifications()); if(modifyDNOperation == null) { // Remove the old ID from the indexes. indexRemoveEntry(txn, oldEntry, entryID); // Insert the new ID into the indexes. indexInsertEntry(txn, newEntry, entryID); } else { // Update indexes only for those attributes that changed. indexModifications(txn, oldEntry, newEntry, entryID, modifyDNOperation.getModifications()); } // Remove the entry from the entry cache. EntryCache entryCache = DirectoryServer.getEntryCache(); @@ -3326,14 +3349,17 @@ */ public static boolean isManageDsaITOperation(Operation operation) { List<Control> controls = operation.getRequestControls(); if (controls != null) if(operation != null) { for (Control control : controls) List<Control> controls = operation.getRequestControls(); if (controls != null) { if (control.getOID().equals(ServerConstants.OID_MANAGE_DSAIT_CONTROL)) for (Control control : controls) { return true; if (control.getOID().equals(ServerConstants.OID_MANAGE_DSAIT_CONTROL)) { return true; } } } } opends/src/server/org/opends/server/backends/jeb/EntryID.java
@@ -28,8 +28,6 @@ import com.sleepycat.je.DatabaseEntry; import java.util.concurrent.atomic.AtomicLong; /** * An integer identifier assigned to each entry in the JE backend. * An entry ID is implemented by this class as a long. @@ -39,11 +37,6 @@ public class EntryID implements Comparable<EntryID> { /** * The cached value of the next identifier to be assigned. */ private static AtomicLong nextid = new AtomicLong(1); /** * The identifier integer value. */ private final Long id; @@ -105,42 +98,6 @@ } /** * Initialize the next ID counter from the previous highest value. * @param highestID The previous highest entry ID. */ public static void initialize(EntryID highestID) { nextid = new AtomicLong(highestID.id + 1); } /** * Assign the next entry ID. * @return The assigned entry ID. */ public static EntryID assignNext() { return new EntryID(nextid.getAndIncrement()); } /** * Return the lowest entry ID assigned. * @return The lowest entry ID assigned. */ public static Long getLowest() { return 1L; } /** * Return the highest entry ID assigned. * @return The highest entry ID assigned. */ public static Long getHighest() { return (nextid.get() - 1); } /** * Compares this object with the specified object for order. Returns a * negative integer, zero, or a positive integer as this object is less * than, equal to, or greater than the specified object.<p> opends/src/server/org/opends/server/backends/jeb/EntryIDSet.java
@@ -598,7 +598,7 @@ } /** * Create an iterator over the set, or over the entire database * Create an iterator over the set or an empty iterator * if the set is not defined. * * @return An EntryID iterator. @@ -608,7 +608,7 @@ if (values == null) { // The set is not defined. return new IndexIteratorAllIds(); return new IDSetIterator(new long[0]); } else { opends/src/server/org/opends/server/backends/jeb/ImportJob.java
@@ -215,20 +215,12 @@ rootContainer.openEntryContainers(config.getBaseDNs()); // Create the import contexts for each base DN. EntryID highestID = null; DN baseDN; for (EntryContainer entryContainer : rootContainer.getEntryContainers()) { baseDN = entryContainer.getBaseDN(); // Keep track of the highest entry ID. EntryID id = entryContainer.getHighestEntryID(); if (highestID == null || id.compareTo(highestID) > 0) { highestID = id; } // Create an import context. ImportContext importContext = new ImportContext(); importContext.setBufferSize(bufferSize); @@ -248,9 +240,6 @@ importMap.put(baseDN, importContext); } // Initialize the entry ID generator. EntryID.initialize(highestID); // Make a note of the time we started. long startTime = System.currentTimeMillis(); @@ -691,7 +680,7 @@ } // Assign a new entry identifier and write the new DN. entryID = EntryID.assignNext(); entryID = rootContainer.getNextEntryID(); dn2id.insert(txn, entryDN, entryID); // Construct a list of IDs up the DIT. opends/src/server/org/opends/server/backends/jeb/IndexIteratorAllIds.java
@@ -35,9 +35,12 @@ { /** * Create a new iterator over all the entry IDs in the backend. * * @param rootContainer The root container where IDs from this * iterator will cover. */ public IndexIteratorAllIds() public IndexIteratorAllIds(RootContainer rootContainer) { super(EntryID.getLowest(), EntryID.getHighest()); super(rootContainer.getLowestEntryID(), rootContainer.getHighestEntryID()); } } opends/src/server/org/opends/server/backends/jeb/RootContainer.java
@@ -40,6 +40,7 @@ import com.sleepycat.je.CheckpointConfig; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.*; import java.io.File; import java.io.FilenameFilter; @@ -108,6 +109,11 @@ private ConcurrentHashMap<DN, EntryContainer> entryContainers; /** * The cached value of the next entry identifier to be assigned. */ private AtomicLong nextid = new AtomicLong(1); /** * Creates a new RootContainer object. Each root container represents a JE * environment. * @@ -238,7 +244,7 @@ */ public EntryContainer openEntryContainer(DN baseDN) throws DatabaseException { EntryContainer ec = new EntryContainer(baseDN, backend, config, env); EntryContainer ec = new EntryContainer(baseDN, backend, config, env, this); EntryContainer ec1=this.entryContainers.get(baseDN); //If an entry container for this baseDN is already open we don't allow //another to be opened. @@ -271,10 +277,19 @@ */ public void openEntryContainers(DN[] baseDNs) throws DatabaseException { EntryID id = null; EntryID highestID = null; for(DN baseDN : baseDNs) { openEntryContainer(baseDN); EntryContainer ec = openEntryContainer(baseDN); id = ec.getHighestEntryID(); if(highestID == null || id.compareTo(highestID) > 0) { highestID = id; } } nextid = new AtomicLong(highestID.longValue() + 1); } /** @@ -625,4 +640,52 @@ { return env.getConfig(); } /** * Get the total number of entries in this root container. * * @return The number of entries in this root container * @throws DatabaseException If an error occurs while retriving the entry * count. */ public long getEntryCount() throws DatabaseException { long entryCount = 0; for(EntryContainer ec : this.entryContainers.values()) { entryCount += ec.getEntryCount(); } return entryCount; } /** * Assign the next entry ID. * * @return The assigned entry ID. */ public EntryID getNextEntryID() { return new EntryID(nextid.getAndIncrement()); } /** * Return the lowest entry ID assigned. * * @return The lowest entry ID assigned. */ public Long getLowestEntryID() { return 1L; } /** * Return the highest entry ID assigned. * * @return The highest entry ID assigned. */ public Long getHighestEntryID() { return (nextid.get() - 1); } } opends/src/server/org/opends/server/messages/JebMessages.java
@@ -1249,6 +1249,13 @@ CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_WARNING | 128; /** * The message ID of an error indicating the entry count of a container can * not be determined. */ public static final int MSGID_JEB_GET_ENTRY_COUNT_FAILED = CATEGORY_MASK_JEB | SEVERITY_MASK_SEVERE_WARNING | 129; /** * Associates a set of generic messages with the message IDs defined in this * class. */ @@ -1743,5 +1750,8 @@ registerMessage(MSGID_JEB_SET_PERMISSIONS_FAILED, "Unable to set file permissions for the backend database " + "directory %s."); registerMessage(MSGID_JEB_GET_ENTRY_COUNT_FAILED, "Unable to determine the total number of entries in the " + "container: %s"); } }