opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryID.java
@@ -22,6 +22,7 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2014 ForgeRock AS */ package org.opends.server.backends.jeb; @@ -35,15 +36,10 @@ */ public class EntryID implements Comparable<EntryID> { /** * The identifier integer value. */ private final Long id; /** * The value in database format, created when necessary. */ private DatabaseEntry data = null; /** The identifier integer value. */ private final long id; /** The value in database format, created when necessary. */ private DatabaseEntry data; /** * Create a new entry ID object from a given long value. @@ -55,15 +51,6 @@ } /** * Create a new entry ID object from a given Long value. * @param id the Long value of the ID. */ public EntryID(Long id) { this.id = id; } /** * Create a new entry ID object from a value in database format. * @param databaseEntry The database value of the ID. */ @@ -108,9 +95,19 @@ * @throws ClassCastException if the specified object's type prevents it * from being compared to this Object. */ @Override public int compareTo(EntryID that) throws ClassCastException { return this.id.compareTo(that.id); final long result = this.id - that.id; if (result < 0) { return -1; } else if (result > 0) { return 1; } return 0; } /** @@ -122,12 +119,9 @@ * @see #hashCode() * @see java.util.Hashtable */ @Override public boolean equals(Object that) @Override public boolean equals(Object that) { if (that == null) { return false; } if (this == that) { return true; @@ -136,7 +130,7 @@ { return false; } return this.id.equals(((EntryID)that).id); return this.id == ((EntryID) that).id; } /** @@ -148,17 +142,19 @@ * @see java.lang.Object#equals(java.lang.Object) * @see java.util.Hashtable */ @Override public int hashCode() @Override public int hashCode() { return (int)id.longValue(); return (int) id; } /** * Get a string representation of this object. * @return A string representation of this object. */ @Override public String toString() { return id.toString(); return Long.toString(id); } } opendj3-server-dev/src/server/org/opends/server/backends/jeb/EntryIDSet.java
@@ -43,7 +43,7 @@ * The IDs are stored here in an array in ascending order. * A null array implies not defined, rather than zero IDs. */ private long[] values = null; private long[] values; /** * The size of the set when it is not defined. This value is only maintained @@ -55,15 +55,13 @@ * The database key containing this set, if the set was constructed * directly from the database. */ private ByteString keyBytes; private final ByteString keyBytes; /** * Create a new undefined set. */ /** Create a new undefined set. */ public EntryIDSet() { values = null; undefinedSize = Long.MAX_VALUE; this.keyBytes = null; this.undefinedSize = Long.MAX_VALUE; } /** @@ -73,8 +71,8 @@ */ public EntryIDSet(long size) { values = null; undefinedSize = size; this.keyBytes = null; this.undefinedSize = size; } /** @@ -110,13 +108,11 @@ if (bytes.length() == 0) { // Entry limit has exceeded and there is no encoded undefined set size. values = null; undefinedSize = Long.MAX_VALUE; } else if ((bytes.byteAt(0) & 0x80) == 0x80) { // Entry limit has exceeded and there is an encoded undefined set size. values = null; undefinedSize = JebFormat.entryIDUndefinedSizeFromDatabase(bytes.toByteArray()); } @@ -137,6 +133,7 @@ */ EntryIDSet(long[] values, int pos, int len) { this.keyBytes = null; this.values = new long[len]; System.arraycopy(values, pos, this.values, 0, len); } @@ -427,12 +424,10 @@ return true; } long id = entryID.longValue(); if (values.length == 0 || id > values[values.length - 1]) { return false; } return Arrays.binarySearch(values, id) >= 0; final long id = entryID.longValue(); return values.length != 0 && id <= values[values.length - 1] && Arrays.binarySearch(values, id) >= 0; } /** @@ -443,7 +438,7 @@ */ public void retainAll(EntryIDSet that) { if (!this.isDefined()) if (!isDefined()) { this.values = that.values; this.undefinedSize = that.undefinedSize; @@ -504,7 +499,7 @@ return; } if (!this.isDefined()) if (!isDefined()) { // Assume there are no overlap between IDs in that set with this set if(undefinedSize != Long.MAX_VALUE) @@ -611,7 +606,7 @@ return; } if (!this.isDefined()) if (!isDefined()) { // Assume all IDs in the given set exists in this set. if(undefinedSize != Long.MAX_VALUE) @@ -680,16 +675,16 @@ @Override public Iterator<EntryID> iterator() { if (values == null) { // The set is not defined. return new IDSetIterator(new long[0]); } else if (values != null) { // The set is defined. return new IDSetIterator(values); } else { // The set is not defined. return new IDSetIterator(new long[0]); } } /** @@ -702,16 +697,16 @@ */ public Iterator<EntryID> iterator(EntryID begin) { if (values == null) { // The set is not defined. return new IDSetIterator(new long[0]); } else if (values != null) { // The set is defined. return new IDSetIterator(values, begin); } else { // The set is not defined. return new IDSetIterator(new long[0]); } } } opendj3-server-dev/src/server/org/opends/server/backends/jeb/ID2Entry.java
@@ -54,22 +54,16 @@ /** * Represents the database containing the LDAP entries. The database key is * the entry ID and the value is the entry contents. * */ public class ID2Entry extends DatabaseContainer { private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** * Parameters for compression and encryption. */ /** Parameters for compression and encryption. */ private DataConfig dataConfig; /** * Cached encoding buffers. */ private static final ThreadLocal<EntryCodec> ENTRY_CODEC_CACHE = new ThreadLocal<EntryCodec>() /** Cached encoding buffers. */ private static final ThreadLocal<EntryCodec> ENTRY_CODEC_CACHE = new ThreadLocal<EntryCodec>() { @Override protected EntryCodec initialValue() @@ -100,8 +94,7 @@ private final ByteStringBuilder encodedBuffer = new ByteStringBuilder(); private final ByteStringBuilder entryBuffer = new ByteStringBuilder(); private final ByteStringBuilder compressedEntryBuffer = new ByteStringBuilder(); private final ByteStringBuilder compressedEntryBuffer = new ByteStringBuilder(); private final ASN1Writer writer; private final int maxBufferSize; @@ -177,12 +170,10 @@ throws DirectoryException { encodeVolatile(entry, dataConfig); return new DatabaseEntry(encodedBuffer.getBackingArray(), 0, encodedBuffer.length()); return new DatabaseEntry(encodedBuffer.getBackingArray(), 0, encodedBuffer.length()); } private void encodeVolatile(Entry entry, DataConfig dataConfig) throws DirectoryException private void encodeVolatile(Entry entry, DataConfig dataConfig) throws DirectoryException { // Encode the entry for later use. entry.encode(entryBuffer, dataConfig.getEntryEncodeConfig()); @@ -199,8 +190,7 @@ { OutputStream compressor = null; try { compressor = new DeflaterOutputStream( compressedEntryBuffer.asOutputStream()); compressor = new DeflaterOutputStream(compressedEntryBuffer.asOutputStream()); entryBuffer.copyTo(compressor); } finally { @@ -238,8 +228,7 @@ * @throws DatabaseException If an error occurs in the JE database. * */ ID2Entry(String name, DataConfig dataConfig, Environment env, EntryContainer entryContainer) ID2Entry(String name, DataConfig dataConfig, Environment env, EntryContainer entryContainer) throws DatabaseException { super(name, env, entryContainer); @@ -365,7 +354,7 @@ { DatabaseEntry data = codec.encodeInternal(entry, dataConfig); OperationStatus status = insert(txn, key, data); return (status == OperationStatus.SUCCESS); return status == OperationStatus.SUCCESS; } finally { @@ -393,7 +382,7 @@ { DatabaseEntry data = codec.encodeInternal(entry, dataConfig); OperationStatus status = put(txn, key, data); return (status == OperationStatus.SUCCESS); return status == OperationStatus.SUCCESS; } finally { @@ -411,8 +400,7 @@ * @throws DatabaseException If an error occurs in the JE database. */ @Override public OperationStatus put(Transaction txn, DatabaseEntry key, DatabaseEntry data) public OperationStatus put(Transaction txn, DatabaseEntry key, DatabaseEntry data) throws DatabaseException { return super.put(txn, key, data); @@ -426,17 +414,11 @@ * @return true if the entry was removed, false if it was not. * @throws DatabaseException If an error occurs in the JE database. */ public boolean remove(Transaction txn, EntryID id) throws DatabaseException public boolean remove(Transaction txn, EntryID id) throws DatabaseException { DatabaseEntry key = id.getDatabaseEntry(); OperationStatus status = delete(txn, key); if (status != OperationStatus.SUCCESS) { return false; } return true; return status == OperationStatus.SUCCESS; } /** opendj3-server-dev/src/server/org/opends/server/backends/jeb/JECompressedSchema.java
@@ -26,22 +26,19 @@ */ package org.opends.server.backends.jeb; import static org.opends.messages.JebMessages.*; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.forgerock.i18n.LocalizableMessage; import org.opends.server.api.CompressedSchema; import org.opends.server.core.DirectoryServer; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.forgerock.opendj.io.ASN1; import org.forgerock.opendj.io.ASN1Reader; import org.forgerock.opendj.io.ASN1Writer; import org.forgerock.opendj.ldap.ByteStringBuilder; import org.opends.server.api.CompressedSchema; import org.opends.server.core.DirectoryServer; import org.opends.server.types.DirectoryException; import org.opends.server.types.InitializationException; import org.opends.server.util.StaticUtils; @@ -53,10 +50,12 @@ import com.sleepycat.je.DatabaseException; import com.sleepycat.je.Environment; import com.sleepycat.je.LockConflictException; import com.sleepycat.je.LockMode; import com.sleepycat.je.OperationStatus; import static com.sleepycat.je.LockMode.*; import static com.sleepycat.je.OperationStatus.*; import static org.opends.messages.JebMessages.*; /** * This class provides a compressed schema implementation whose definitions are @@ -64,36 +63,24 @@ */ public final class JECompressedSchema extends CompressedSchema { /** * The name of the database used to store compressed attribute description * definitions. */ private static final String DB_NAME_AD = "compressed_attributes"; /** * The name of the database used to store compressed object class set * definitions. */ private static final String DB_NAME_OC = "compressed_object_classes"; private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** The name of the database used to store compressed attribute description definitions. */ private static final String DB_NAME_AD = "compressed_attributes"; /** The name of the database used to store compressed object class set definitions. */ private static final String DB_NAME_OC = "compressed_object_classes"; /** The compressed attribute description schema database. */ private Database adDatabase; /** The environment in which the databases are held. */ private Environment environment; /** The compressed object class set schema database. */ private Database ocDatabase; private final ByteStringBuilder storeAttributeWriterBuffer = new ByteStringBuilder(); private final ASN1Writer storeAttributeWriter = ASN1 .getWriter(storeAttributeWriterBuffer); private final ByteStringBuilder storeObjectClassesWriterBuffer = new ByteStringBuilder(); private final ASN1Writer storeObjectClassesWriter = ASN1 .getWriter(storeObjectClassesWriterBuffer); private final ByteStringBuilder storeAttributeWriterBuffer = new ByteStringBuilder(); private final ASN1Writer storeAttributeWriter = ASN1.getWriter(storeAttributeWriterBuffer); private final ByteStringBuilder storeObjectClassesWriterBuffer = new ByteStringBuilder(); private final ASN1Writer storeObjectClassesWriter = ASN1.getWriter(storeObjectClassesWriterBuffer); @@ -125,38 +112,30 @@ */ public void close() { try { adDatabase.sync(); } catch (final Exception e) { // Ignore. } StaticUtils.close(adDatabase); try { ocDatabase.sync(); } catch (final Exception e) { // Ignore. } StaticUtils.close(ocDatabase); close0(adDatabase); close0(ocDatabase); adDatabase = null; ocDatabase = null; environment = null; } private void close0(Database database) { try { database.sync(); } catch (final Exception e) { // Ignore. } StaticUtils.close(database); } /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override protected void storeAttribute(final byte[] encodedAttribute, final String attributeName, final Collection<String> attributeOptions) @@ -182,9 +161,7 @@ /** * {@inheritDoc} */ /** {@inheritDoc} */ @Override protected void storeObjectClasses(final byte[] encodedObjectClasses, final Collection<String> objectClassNames) throws DirectoryException @@ -250,9 +227,8 @@ { final DatabaseEntry keyEntry = new DatabaseEntry(); final DatabaseEntry valueEntry = new DatabaseEntry(); OperationStatus status = ocCursor.getFirst(keyEntry, valueEntry, LockMode.READ_UNCOMMITTED); while (status == OperationStatus.SUCCESS) OperationStatus status = ocCursor.getFirst(keyEntry, valueEntry, READ_UNCOMMITTED); while (status == SUCCESS) { final byte[] encodedObjectClasses = keyEntry.getData(); final ASN1Reader reader = ASN1.getReader(valueEntry.getData()); @@ -264,8 +240,7 @@ } reader.readEndSequence(); loadObjectClasses(encodedObjectClasses, objectClassNames); status = ocCursor.getNext(keyEntry, valueEntry, LockMode.READ_UNCOMMITTED); status = ocCursor.getNext(keyEntry, valueEntry, READ_UNCOMMITTED); } } catch (final IOException e) @@ -286,9 +261,8 @@ { final DatabaseEntry keyEntry = new DatabaseEntry(); final DatabaseEntry valueEntry = new DatabaseEntry(); OperationStatus status = adCursor.getFirst(keyEntry, valueEntry, LockMode.READ_UNCOMMITTED); while (status == OperationStatus.SUCCESS) OperationStatus status = adCursor.getFirst(keyEntry, valueEntry, READ_UNCOMMITTED); while (status == SUCCESS) { final byte[] encodedAttribute = keyEntry.getData(); final ASN1Reader reader = ASN1.getReader(valueEntry.getData()); @@ -301,8 +275,7 @@ } reader.readEndSequence(); loadAttribute(encodedAttribute, attributeName, attributeOptions); status = adCursor.getNext(keyEntry, valueEntry, LockMode.READ_UNCOMMITTED); status = adCursor.getNext(keyEntry, valueEntry, READ_UNCOMMITTED); } } catch (final IOException e) @@ -319,29 +292,31 @@ private void store(final Database database, final byte[] key, final ByteStringBuilder value) throws DirectoryException private void store(final Database database, final byte[] key, final ByteStringBuilder value) throws DirectoryException { boolean successful = false; if (!putNoOverwrite(database, key, value)) { final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_MULTIPLE_FAILURES.get(); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m); } } private boolean putNoOverwrite(final Database database, final byte[] key, final ByteStringBuilder value) throws DirectoryException { final DatabaseEntry keyEntry = new DatabaseEntry(key); final DatabaseEntry valueEntry = new DatabaseEntry(value.getBackingArray(), 0, value.length()); final DatabaseEntry valueEntry = new DatabaseEntry(value.getBackingArray(), 0, value.length()); for (int i = 0; i < 3; i++) { try { final OperationStatus status = database.putNoOverwrite(null, keyEntry, valueEntry); if (status == OperationStatus.SUCCESS) { successful = true; break; } else final OperationStatus status = database.putNoOverwrite(null, keyEntry, valueEntry); if (status != SUCCESS) { final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_STATUS.get(status); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m); } return true; } catch (final LockConflictException ce) { @@ -349,19 +324,11 @@ } catch (final DatabaseException de) { final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_EX.get(de .getMessage()); throw new DirectoryException( DirectoryServer.getServerErrorResultCode(), m, de); final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_EX.get(de.getMessage()); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m, de); } } if (!successful) { final LocalizableMessage m = ERR_JEB_COMPSCHEMA_CANNOT_STORE_MULTIPLE_FAILURES.get(); throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), m); } return false; } }