OPENDJ-1855: Reformat and cleanup pluggable backend code: adjust visibility, findbugs, ucdetector, etc...
Performed first pass in order to facilitate future refactoring:
* remove some unused classes/methods. There are some remaining unused methods but these look like they are going to be needed for the migration of the JE import
* reduced visibility of many classes, methods, and fields
* added final to some methods and fields
* fixed some minor Java/Javadoc warnings.
55 files modified
1 files deleted
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public long numSubordinates(DN entryDN, boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | |
| | | public abstract void preloadEntryCache() throws UnsupportedOperationException; |
| | | |
| | | /** |
| | | * Indicates whether the data associated with this backend may be |
| | | * considered local (i.e., in a repository managed by the Directory |
| | | * Server) rather than remote (i.e., in an external repository |
| | | * accessed by the Directory Server but managed through some other |
| | | * means). |
| | | * |
| | | * @return {@code true} if the data associated with this backend |
| | | * may be considered local, or {@code false} if it is |
| | | * remote. |
| | | */ |
| | | public abstract boolean isLocal(); |
| | | |
| | | /** |
| | | * Indicates whether search operations which target the specified |
| | | * attribute in the indicated manner would be considered indexed |
| | | * in this backend. The operation should be considered indexed only |
| | |
| | | */ |
| | | public abstract Set<String> getSupportedFeatures(); |
| | | |
| | | /** |
| | | * Indicates whether this backend supports the specified feature. |
| | | * |
| | | * @param featureOID The OID of the feature for which to make the |
| | | * determination. |
| | | * |
| | | * @return {@code true} if this backend supports the feature with |
| | | * the specified OID, or {@code false} if it does not. |
| | | */ |
| | | public final boolean supportsFeature(String featureOID) |
| | | { |
| | | Set<String> supportedFeatures = getSupportedFeatures(); |
| | | return supportedFeatures != null && supportedFeatures.contains(featureOID); |
| | | } |
| | | |
| | | /** Enumeration of optional backend operations. */ |
| | | public static enum BackendOperation |
| | | { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Specifies the set of subordinate backends for this backend. |
| | | * |
| | | * @param subordinateBackends The set of subordinate backends for |
| | | * this backend. |
| | | */ |
| | | public final synchronized void setSubordinateBackends(Backend<?>[] subordinateBackends) |
| | | { |
| | | this.subordinateBackends = subordinateBackends; |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided backend to the set of subordinate backends for |
| | | * this backend. |
| | | * |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(final AttributeType attributeType, final IndexType indexType) |
| | | { |
| | | return true; |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public long numSubordinates(final DN entryDN, final boolean subtree) |
| | | throws DirectoryException |
| | | { |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | logger.info(NOTE_BACKEND_OFFLINE, cfg.getBackendId()); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | |
| | | * by the ordering matching rule. If these could be guaranteed to be identical |
| | | * then we would not need a separate ordering index. |
| | | */ |
| | | public class AttributeIndex |
| | | class AttributeIndex |
| | | implements ConfigurationChangeListener<BackendIndexCfg>, Closeable |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | |
| | | * @param txn The database transaction |
| | | * @throws ConfigException if a configuration related error occurs. |
| | | */ |
| | | public AttributeIndex(BackendIndexCfg indexConfig, EntryContainer entryContainer, WriteableStorage txn) |
| | | AttributeIndex(BackendIndexCfg indexConfig, EntryContainer entryContainer, WriteableStorage txn) |
| | | throws ConfigException |
| | | { |
| | | this.entryContainer = entryContainer; |
| | |
| | | * Get the attribute type of this attribute index. |
| | | * @return The attribute type of this attribute index. |
| | | */ |
| | | public AttributeType getAttributeType() |
| | | AttributeType getAttributeType() |
| | | { |
| | | return indexConfig.getAttribute(); |
| | | } |
| | |
| | | * |
| | | * @return the indexing options of this AttributeIndex. |
| | | */ |
| | | public IndexingOptions getIndexingOptions() |
| | | IndexingOptions getIndexingOptions() |
| | | { |
| | | return indexingOptions; |
| | | } |
| | |
| | | * Get the JE index configuration used by this index. |
| | | * @return The configuration in effect. |
| | | */ |
| | | public BackendIndexCfg getConfiguration() |
| | | BackendIndexCfg getConfiguration() |
| | | { |
| | | return indexConfig; |
| | | } |
| | |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | public void addEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | void addEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | for (Index index : nameToIndexes.values()) |
| | |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | public void removeEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | void removeEntry(IndexBuffer buffer, EntryID entryID, Entry entry) |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | for (Index index : nameToIndexes.values()) |
| | |
| | | * @throws StorageRuntimeException If an error occurs during an operation on a |
| | | * JE database. |
| | | */ |
| | | public void modifyEntry(IndexBuffer buffer, |
| | | void modifyEntry(IndexBuffer buffer, |
| | | EntryID entryID, |
| | | Entry oldEntry, |
| | | Entry newEntry, |
| | |
| | | * filter usage statistics. |
| | | * @return The candidate entry IDs that might contain match both filters. |
| | | */ |
| | | public EntryIDSet evaluateBoundedRange(IndexQueryFactory<IndexQuery> indexQueryFactory, |
| | | EntryIDSet evaluateBoundedRange(IndexQueryFactory<IndexQuery> indexQueryFactory, |
| | | SearchFilter filter1, SearchFilter filter2, StringBuilder debugBuffer, DatabaseEnvironmentMonitor monitor) |
| | | { |
| | | // TODO : this implementation is not optimal |
| | |
| | | * @return The candidate entry IDs that might contain a value |
| | | * that matches the filter type. |
| | | */ |
| | | public EntryIDSet evaluateFilter(IndexQueryFactory<IndexQuery> indexQueryFactory, IndexFilterType indexFilterType, |
| | | EntryIDSet evaluateFilter(IndexQueryFactory<IndexQuery> indexQueryFactory, |
| | | IndexFilterType indexFilterType, |
| | | SearchFilter filter, StringBuilder debugBuffer, DatabaseEnvironmentMonitor monitor) |
| | | { |
| | | try |
| | |
| | | * |
| | | * @return The number of values that have exceeded the entry limit. |
| | | */ |
| | | public long getEntryLimitExceededCount() |
| | | long getEntryLimitExceededCount() |
| | | { |
| | | long entryLimitExceededCount = 0; |
| | | |
| | |
| | | * Get a list of the databases opened by this attribute index. |
| | | * @param dbList A list of database containers. |
| | | */ |
| | | public void listDatabases(List<DatabaseContainer> dbList) |
| | | void listDatabases(List<DatabaseContainer> dbList) |
| | | { |
| | | dbList.addAll(nameToIndexes.values()); |
| | | } |
| | |
| | | * Return true iff this index is trusted. |
| | | * @return the trusted state of this index |
| | | */ |
| | | public boolean isTrusted() |
| | | boolean isTrusted() |
| | | { |
| | | for (Index index : nameToIndexes.values()) |
| | | { |
| | |
| | | * |
| | | * @return JE database name for this database container. |
| | | */ |
| | | public String getName() |
| | | String getName() |
| | | { |
| | | return entryContainer.getDatabasePrefix() |
| | | + "_" |
| | |
| | | * |
| | | * @return The equality index. |
| | | */ |
| | | public Index getEqualityIndex() { |
| | | Index getEqualityIndex() |
| | | { |
| | | return getIndexById(IndexType.EQUALITY.toString()); |
| | | } |
| | | |
| | |
| | | * |
| | | * @return The approximate index. |
| | | */ |
| | | public Index getApproximateIndex() { |
| | | Index getApproximateIndex() |
| | | { |
| | | return getIndexById(IndexType.APPROXIMATE.toString()); |
| | | } |
| | | |
| | |
| | | * |
| | | * @return The ordering index. |
| | | */ |
| | | public Index getOrderingIndex() { |
| | | Index getOrderingIndex() |
| | | { |
| | | return getIndexById(IndexType.ORDERING.toString()); |
| | | } |
| | | |
| | |
| | | * |
| | | * @return The substring index. |
| | | */ |
| | | public Index getSubstringIndex() { |
| | | Index getSubstringIndex() |
| | | { |
| | | return getIndexById(IndexType.SUBSTRING.toString()); |
| | | } |
| | | |
| | |
| | | * |
| | | * @return The presence index. |
| | | */ |
| | | public Index getPresenceIndex() { |
| | | Index getPresenceIndex() |
| | | { |
| | | return getIndexById(IndexType.PRESENCE.toString()); |
| | | } |
| | | |
| | |
| | | * @return The index identified by the provided identifier, or null if no such |
| | | * index exists |
| | | */ |
| | | public Index getIndexById(String indexId) |
| | | Index getIndexById(String indexId) |
| | | { |
| | | return nameToIndexes.get(indexId); |
| | | } |
| | |
| | | * |
| | | * @return The map containing entries (extensible index type, list of indexes) |
| | | */ |
| | | public Map<String, Collection<Index>> getExtensibleIndexes() |
| | | Map<String, Collection<Index>> getExtensibleIndexes() |
| | | { |
| | | return extensibleIndexesMapping; |
| | | } |
| | |
| | | * @return A collection of all indexes in use by this attribute |
| | | * index. |
| | | */ |
| | | public Collection<Index> getAllIndexes() { |
| | | Collection<Index> getAllIndexes() |
| | | { |
| | | return new LinkedHashSet<Index>(nameToIndexes.values()); |
| | | } |
| | | |
| | |
| | | * @return The candidate entry IDs that might contain the filter |
| | | * assertion value. |
| | | */ |
| | | public EntryIDSet evaluateExtensibleFilter(IndexQueryFactory<IndexQuery> indexQueryFactory, SearchFilter filter, |
| | | EntryIDSet evaluateExtensibleFilter(IndexQueryFactory<IndexQuery> indexQueryFactory, |
| | | SearchFilter filter, |
| | | StringBuilder debugBuffer, DatabaseEnvironmentMonitor monitor) |
| | | { |
| | | //Get the Matching Rule OID of the filter. |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | /** |
| | | * This class implements an attribute indexer for matching rules in JE Backend. |
| | | */ |
| | | public final class AttributeIndexer extends Indexer |
| | | final class AttributeIndexer extends Indexer |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | * required. |
| | | * @param extensibleIndexer The extensible indexer to be used. |
| | | */ |
| | | public AttributeIndexer(AttributeType attributeType, org.forgerock.opendj.ldap.spi.Indexer extensibleIndexer) |
| | | AttributeIndexer(AttributeType attributeType, |
| | | org.forgerock.opendj.ldap.spi.Indexer extensibleIndexer) |
| | | { |
| | | this.attributeType = attributeType; |
| | | this.indexer = extensibleIndexer; |
| | |
| | | logger.info(NOTE_BACKEND_OFFLINE, cfg.getBackendId()); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | |
| | | * |
| | | * @return The RootContainer object currently used by this backend. |
| | | */ |
| | | public RootContainer getRootContainer() |
| | | public final RootContainer getRootContainer() |
| | | { |
| | | return rootContainer; |
| | | } |
| | |
| | | * that is not related to the server |
| | | * configuration. |
| | | */ |
| | | public RootContainer getReadOnlyRootContainer() |
| | | private final RootContainer getReadOnlyRootContainer() |
| | | throws ConfigException, InitializationException |
| | | { |
| | | return initializeRootContainer(); |
| | |
| | | /** |
| | | * A backup manager for backends. |
| | | */ |
| | | public class BackupManager |
| | | class BackupManager |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | /** |
| | | * The common prefix for archive files. |
| | | */ |
| | | public static final String BACKUP_BASE_FILENAME = "backup-"; |
| | | private static final String BACKUP_BASE_FILENAME = "backup-"; |
| | | |
| | | /** |
| | | * The name of the property that holds the name of the latest log file |
| | | * at the time the backup was created. |
| | | */ |
| | | public static final String PROPERTY_LAST_LOGFILE_NAME = "last_logfile_name"; |
| | | private static final String PROPERTY_LAST_LOGFILE_NAME = "last_logfile_name"; |
| | | |
| | | /** |
| | | * The name of the property that holds the size of the latest log file |
| | | * at the time the backup was created. |
| | | */ |
| | | public static final String PROPERTY_LAST_LOGFILE_SIZE = "last_logfile_size"; |
| | | private static final String PROPERTY_LAST_LOGFILE_SIZE = "last_logfile_size"; |
| | | |
| | | |
| | | /** |
| | |
| | | * containing a list of log files that are unchanged since the |
| | | * previous backup. |
| | | */ |
| | | public static final String ZIPENTRY_UNCHANGED_LOGFILES = "unchanged.txt"; |
| | | private static final String ZIPENTRY_UNCHANGED_LOGFILES = "unchanged.txt"; |
| | | |
| | | /** |
| | | * The name of a dummy entry in the backup archive file that will act |
| | | * as a placeholder in case a backup is done on an empty backend. |
| | | */ |
| | | public static final String ZIPENTRY_EMPTY_PLACEHOLDER = "empty.placeholder"; |
| | | private static final String ZIPENTRY_EMPTY_PLACEHOLDER = "empty.placeholder"; |
| | | |
| | | |
| | | /** |
| | | * The backend ID. |
| | | */ |
| | | private String backendID; |
| | | private final String backendID; |
| | | |
| | | |
| | | /** |
| | |
| | | * @param backendID The ID of the backend instance for which a backup |
| | | * manager is required. |
| | | */ |
| | | public BackupManager(String backendID) |
| | | BackupManager(String backendID) |
| | | { |
| | | this.backendID = backendID; |
| | | } |
| | |
| | | * @param backupConfig The configuration to use when performing the backup. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | public void createBackup(File backendDir, BackupConfig backupConfig) |
| | | void createBackup(File backendDir, BackupConfig backupConfig) |
| | | throws DirectoryException |
| | | { |
| | | // Get the properties to use for the backup. |
| | |
| | | * @param restoreConfig The configuration to use when performing the restore. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | public void restoreBackup(File backendDir, |
| | | void restoreBackup(File backendDir, |
| | | RestoreConfig restoreConfig) |
| | | throws DirectoryException |
| | | { |
| | |
| | | * exists or there are other backups that are |
| | | * dependent upon it). |
| | | */ |
| | | public void removeBackup(BackupDirectory backupDir, |
| | | void removeBackup(BackupDirectory backupDir, |
| | | String backupID) |
| | | throws DirectoryException |
| | | { |
| | |
| | | * for each entry. The key is the normalized entry DN and the value |
| | | * is the entry ID. |
| | | */ |
| | | public class DN2ID extends DatabaseContainer |
| | | class DN2ID extends DatabaseContainer |
| | | { |
| | | private final int prefixRDNComponents; |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Write a record to the DN database. If a record with the given key already |
| | | * exists, the record will be replaced, otherwise a new record will be |
| | | * inserted. |
| | | * @param txn A JE database transaction to be used for the database operation, |
| | | * or null if none. |
| | | * @param dn The entry DN, which is the key to the record. |
| | | * @param id The entry ID, which is the value of the record. |
| | | * @throws StorageRuntimeException If an error occurred while attempting to write |
| | | * the record. |
| | | */ |
| | | public void put(WriteableStorage txn, DN dn, EntryID id) throws StorageRuntimeException |
| | | { |
| | | ByteString key = dnToDNKey(dn, prefixRDNComponents); |
| | | ByteString value = id.toByteString(); |
| | | |
| | | put(txn, key, value); |
| | | } |
| | | |
| | | /** |
| | | * Write a record to the DN database, where the key and value are already |
| | | * formatted. |
| | | * |
| | |
| | | * as in the DN database so that all referrals in a subtree can be retrieved by |
| | | * cursoring through a range of the records. |
| | | */ |
| | | public class DN2URI extends DatabaseContainer |
| | | class DN2URI extends DatabaseContainer |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | * @return true if the values were deleted, false if not. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | boolean delete(WriteableStorage txn, DN dn) throws StorageRuntimeException |
| | | private boolean delete(WriteableStorage txn, DN dn) throws StorageRuntimeException |
| | | { |
| | | ByteString key = toKey(dn); |
| | | |
| | |
| | | * @return true if the value was deleted, false if not. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | boolean delete(WriteableStorage txn, DN dn, Collection<String> labeledURIs) throws StorageRuntimeException |
| | | private boolean delete(WriteableStorage txn, DN dn, Collection<String> labeledURIs) |
| | | throws StorageRuntimeException |
| | | { |
| | | ByteString key = toKey(dn); |
| | | |
| | |
| | | * @throws StorageRuntimeException |
| | | * If an error occurs in the JE database. |
| | | */ |
| | | public void replaceEntry(WriteableStorage txn, Entry before, Entry after) |
| | | void replaceEntry(WriteableStorage txn, Entry before, Entry after) |
| | | throws StorageRuntimeException |
| | | { |
| | | deleteEntry(txn, before); |
| | |
| | | * @return True if the entry was added successfully or False otherwise. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public boolean addEntry(WriteableStorage txn, Entry entry) |
| | | boolean addEntry(WriteableStorage txn, Entry entry) |
| | | throws StorageRuntimeException |
| | | { |
| | | Set<String> labeledURIs = entry.getReferralURLs(); |
| | |
| | | * DN. The referral URLs will be set appropriately for the references found |
| | | * in the referral entry. |
| | | */ |
| | | void throwReferralException(DN targetDN, DN referralDN, Collection<String> labeledURIs, SearchScope searchScope) |
| | | private void throwReferralException(DN targetDN, DN referralDN, Collection<String> labeledURIs, |
| | | SearchScope searchScope) |
| | | throws DirectoryException |
| | | { |
| | | ArrayList<String> URIList = new ArrayList<String>(labeledURIs.size()); |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * Configuration class to indicate desired compression and cryptographic options |
| | | * for the data stored in the database. |
| | | */ |
| | | public final class DataConfig |
| | | final class DataConfig |
| | | { |
| | | /** Indicates whether data should be compressed before writing to the database. */ |
| | | private boolean compressed; |
| | | |
| | | /** The configuration to use when encoding entries in the database. */ |
| | | private EntryEncodeConfig encodeConfig = new EntryEncodeConfig(); |
| | | private EntryEncodeConfig encodeConfig; |
| | | |
| | | /** |
| | | * Construct a new DataConfig object with the specified settings. |
| | |
| | | * @param compressedSchema the compressed schema manager to use. It must not |
| | | * be {@code null} if compactEncoding is {@code true}. |
| | | */ |
| | | public DataConfig(boolean compressed, boolean compactEncoding, CompressedSchema compressedSchema) |
| | | DataConfig(boolean compressed, boolean compactEncoding, CompressedSchema compressedSchema) |
| | | { |
| | | this.compressed = compressed; |
| | | setCompactEncoding(compactEncoding, compressedSchema); |
| | | } |
| | | |
| | | /** |
| | | * Determine whether data should be compressed before writing to the database. |
| | | * @return true if data should be compressed, false if not. |
| | | */ |
| | | public boolean isCompressed() |
| | | { |
| | | return compressed; |
| | | } |
| | | |
| | | /** |
| | | * Determine whether entries should be encoded with the compact form before |
| | | * writing to the database. |
| | | * @return true if data should be encoded in the compact form. |
| | | */ |
| | | public boolean isCompactEncoding() |
| | | { |
| | | return encodeConfig.compressAttributeDescriptions(); |
| | | } |
| | | |
| | | /** |
| | | * Configure whether data should be compressed before writing to the database. |
| | | * @param compressed true if data should be compressed, false if not. |
| | | */ |
| | | public void setCompressed(boolean compressed) |
| | | { |
| | | this.compressed = compressed; |
| | | } |
| | | |
| | | /** |
| | | * Configure whether data should be encoded with the compact form before |
| | | * writing to the database. |
| | | * @param compactEncoding true if data should be encoded in compact form, |
| | | * false if not. |
| | | * @param compressedSchema The compressed schema manager to use. It must not |
| | | * be {@code null} if compactEncoding is {@code true}. |
| | | */ |
| | | public void setCompactEncoding(boolean compactEncoding, CompressedSchema compressedSchema) |
| | | { |
| | | if (compressedSchema == null) |
| | | { |
| | | Reject.ifTrue(compactEncoding); |
| | |
| | | } |
| | | else |
| | | { |
| | | this.encodeConfig = new EntryEncodeConfig(false, compactEncoding, compactEncoding, compressedSchema); |
| | | this.encodeConfig = |
| | | new EntryEncodeConfig(false, compactEncoding, compactEncoding, compressedSchema); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Determine whether data should be compressed before writing to the database. |
| | | * @return true if data should be compressed, false if not. |
| | | */ |
| | | boolean isCompressed() |
| | | { |
| | | return compressed; |
| | | } |
| | | |
| | | /** |
| | | * Get the EntryEncodeConfig object in use by this configuration. |
| | | * @return the EntryEncodeConfig object in use by this configuration. |
| | | */ |
| | | public EntryEncodeConfig getEntryEncodeConfig() |
| | | EntryEncodeConfig getEntryEncodeConfig() |
| | | { |
| | | return this.encodeConfig; |
| | | return encodeConfig; |
| | | } |
| | | |
| | | /** |
| | |
| | | * This class is a wrapper around the JE database object and provides basic |
| | | * read and write methods for entries. |
| | | */ |
| | | public abstract class DatabaseContainer implements Closeable |
| | | abstract class DatabaseContainer implements Closeable |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | * @throws StorageRuntimeException If an error occurs while attempting to open |
| | | * the cursor. |
| | | */ |
| | | public Cursor openCursor(ReadableStorage txn) throws StorageRuntimeException |
| | | final Cursor openCursor(ReadableStorage txn) throws StorageRuntimeException |
| | | { |
| | | return txn.openCursor(treeName); |
| | | } |
| | |
| | | * |
| | | * @return JE database name for this database container. |
| | | */ |
| | | public TreeName getName() |
| | | final TreeName getName() |
| | | { |
| | | return treeName; |
| | | } |
| | |
| | | * |
| | | * @param name The database name to use for this container. |
| | | */ |
| | | void setName(TreeName name) |
| | | final void setName(TreeName name) |
| | | { |
| | | this.treeName = name; |
| | | } |
| | |
| | | * It uses reflection on the environment statistics object |
| | | * so that we don't need to keep a list of all the stats. |
| | | */ |
| | | public class DatabaseEnvironmentMonitor |
| | | class DatabaseEnvironmentMonitor |
| | | extends MonitorProvider<MonitorProviderCfg> |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | |
| | | } |
| | | |
| | | /** The name of this monitor instance. */ |
| | | private String name; |
| | | private final String name; |
| | | |
| | | /** The root container to be monitored. */ |
| | | private RootContainer rootContainer; |
| | | private final RootContainer rootContainer; |
| | | |
| | | private int maxEntries = 1024; |
| | | private boolean filterUseEnabled; |
| | |
| | | * @param rootContainer A root container handle for the database to be |
| | | * monitored. |
| | | */ |
| | | public DatabaseEnvironmentMonitor(String name, RootContainer rootContainer) |
| | | DatabaseEnvironmentMonitor(String name, RootContainer rootContainer) |
| | | { |
| | | this.name = name; |
| | | this.rootContainer = rootContainer; |
| | |
| | | * @param searchFilter The search filter that was evaluated. |
| | | * @param failureMessage The reason why an index was not used. |
| | | */ |
| | | public void updateStats(SearchFilter searchFilter, LocalizableMessage failureMessage) |
| | | void updateStats(SearchFilter searchFilter, LocalizableMessage failureMessage) |
| | | { |
| | | if(!filterUseEnabled) |
| | | { |
| | |
| | | * @param matchingEntries The number of entries matched by the successful |
| | | * index lookup. |
| | | */ |
| | | public void updateStats(SearchFilter searchFilter, long matchingEntries) |
| | | void updateStats(SearchFilter searchFilter, long matchingEntries) |
| | | { |
| | | if(!filterUseEnabled) |
| | | { |
| | |
| | | * |
| | | * @param enabled <code>true></code> to enable index filter statics gathering. |
| | | */ |
| | | public void enableFilterUseStats(boolean enabled) |
| | | void enableFilterUseStats(boolean enabled) |
| | | { |
| | | if(enabled && !filterUseEnabled) |
| | | { |
| | |
| | | * |
| | | * @return <code>true</code> If index filter statistics gathering is enabled. |
| | | */ |
| | | public boolean isFilterUseEnabled() |
| | | boolean isFilterUseEnabled() |
| | | { |
| | | return filterUseEnabled; |
| | | } |
| | |
| | | * @param maxEntries The maximum number of search filters statistics |
| | | * entries to keep |
| | | */ |
| | | public void setMaxEntries(int maxEntries) { |
| | | void setMaxEntries(int maxEntries) |
| | | { |
| | | this.maxEntries = maxEntries; |
| | | } |
| | | |
| | | /** |
| | | * Updates the statistics counter to include an indexed search. |
| | | */ |
| | | public void updateIndexedSearchCount() |
| | | void updateIndexedSearchCount() |
| | | { |
| | | indexedSearchCount.getAndIncrement(); |
| | | } |
| | |
| | | /** |
| | | * Updates the statistics counter to include an unindexed search. |
| | | */ |
| | | public void updateUnindexedSearchCount() |
| | | void updateUnindexedSearchCount() |
| | | { |
| | | unindexedSearchCount.getAndIncrement(); |
| | | } |
| | |
| | | * This comparator is used to sort databases in order of priority |
| | | * for preloading into the cache. |
| | | */ |
| | | public class DbPreloadComparator |
| | | class DbPreloadComparator |
| | | implements Comparator<DatabaseContainer> |
| | | { |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | /** |
| | | * BackendImpl object. |
| | | */ |
| | | private BackendImpl backend; |
| | | private final BackendImpl backend; |
| | | |
| | | /** |
| | | * Interrupt flag for the arbiter to terminate worker threads. |
| | | */ |
| | | private AtomicBoolean interruptFlag = new AtomicBoolean(false); |
| | | private final AtomicBoolean interruptFlag = new AtomicBoolean(false); |
| | | |
| | | /** |
| | | * Processed entries counter. |
| | | */ |
| | | private AtomicLong processedEntries = new AtomicLong(0); |
| | | private final AtomicLong processedEntries = new AtomicLong(0); |
| | | |
| | | /** |
| | | * Progress report resolution. |
| | |
| | | /** |
| | | * Default resolution time. |
| | | */ |
| | | public static final long |
| | | private static final long |
| | | PRELOAD_DEFAULT_SLEEP_TIME = 10000; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * Default queue capacity. |
| | | */ |
| | | public static final int |
| | | private static final int |
| | | PRELOAD_DEFAULT_QUEUE_CAPACITY = 128; |
| | | |
| | | /** |
| | |
| | | /** |
| | | * Worker threads. |
| | | */ |
| | | private List<Thread> preloadThreads = |
| | | private final List<Thread> preloadThreads = |
| | | Collections.synchronizedList( |
| | | new LinkedList<Thread>()); |
| | | |
| | | /** |
| | | * Collector thread. |
| | | */ |
| | | private EntryCacheCollector collector = |
| | | private final EntryCacheCollector collector = |
| | | new EntryCacheCollector(); |
| | | |
| | | /** |
| | | * This queue is for workers to take from. |
| | | */ |
| | | private LinkedBlockingQueue<PreloadEntry> entryQueue; |
| | | private final LinkedBlockingQueue<PreloadEntry> entryQueue; |
| | | |
| | | /** |
| | | * The number of bytes in a megabyte. |
| | |
| | | private class PreloadEntry { |
| | | |
| | | // Encoded Entry. |
| | | public ByteString entryBytes; |
| | | private ByteString entryBytes; |
| | | |
| | | // Encoded EntryID. |
| | | public ByteString entryIDBytes; |
| | | private ByteString entryIDBytes; |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | public PreloadEntry(ByteString entryBytes, ByteString entryIDBytes) |
| | | private PreloadEntry(ByteString entryBytes, ByteString entryIDBytes) |
| | | { |
| | | this.entryBytes = entryBytes; |
| | | this.entryIDBytes = entryIDBytes; |
| | |
| | | * Prevents name clashes for common indexes (like id2entry) across multiple suffixes. |
| | | * For example when a root container contains multiple suffixes. |
| | | */ |
| | | private String databasePrefix; |
| | | private final String databasePrefix; |
| | | |
| | | /** |
| | | * This class is responsible for managing the configuration for attribute |
| | |
| | | * @return A reference to the root container in which this entry container |
| | | * exists. |
| | | */ |
| | | public RootContainer getRootContainer() |
| | | RootContainer getRootContainer() |
| | | { |
| | | return rootContainer; |
| | | } |
| | |
| | | * |
| | | * @return The DN database. |
| | | */ |
| | | public DN2ID getDN2ID() |
| | | DN2ID getDN2ID() |
| | | { |
| | | return dn2id; |
| | | } |
| | |
| | | * |
| | | * @return The entry database. |
| | | */ |
| | | public ID2Entry getID2Entry() |
| | | ID2Entry getID2Entry() |
| | | { |
| | | return id2entry; |
| | | } |
| | |
| | | * |
| | | * @return The referral database. |
| | | */ |
| | | public DN2URI getDN2URI() |
| | | DN2URI getDN2URI() |
| | | { |
| | | return dn2uri; |
| | | } |
| | |
| | | * |
| | | * @return The children database. |
| | | */ |
| | | public Index getID2Children() |
| | | Index getID2Children() |
| | | { |
| | | return id2children; |
| | | } |
| | |
| | | * |
| | | * @return The subtree database. |
| | | */ |
| | | public Index getID2Subtree() |
| | | Index getID2Subtree() |
| | | { |
| | | return id2subtree; |
| | | } |
| | | |
| | | /** |
| | | * Get the state database used by this entry container. |
| | | * The entry container must have been opened. |
| | | * |
| | | * @return The state database. |
| | | */ |
| | | public State getState() |
| | | { |
| | | return state; |
| | | } |
| | | |
| | | /** |
| | | * Look for an attribute index for the given attribute type. |
| | | * |
| | | * @param attrType The attribute type for which an attribute index is needed. |
| | |
| | | * |
| | | * @return The attribute index map. |
| | | */ |
| | | public Map<AttributeType, AttributeIndex> getAttributeIndexMap() { |
| | | Map<AttributeType, AttributeIndex> getAttributeIndexMap() |
| | | { |
| | | return attrIndexMap; |
| | | } |
| | | |
| | |
| | | * |
| | | * @return All attribute indexes defined in this entry container. |
| | | */ |
| | | public Collection<AttributeIndex> getAttributeIndexes() |
| | | Collection<AttributeIndex> getAttributeIndexes() |
| | | { |
| | | return attrIndexMap.values(); |
| | | } |
| | |
| | | * |
| | | * @return The collection of VLV indexes defined in this entry container. |
| | | */ |
| | | public Collection<VLVIndex> getVLVIndexes() |
| | | Collection<VLVIndex> getVLVIndexes() |
| | | { |
| | | return vlvIndexMap.values(); |
| | | } |
| | |
| | | Entry getEntry(ReadableStorage txn, EntryID entryID) throws DirectoryException |
| | | { |
| | | // Try the entry cache first. |
| | | final EntryCache entryCache = getEntryCache(); |
| | | final EntryCache<?> entryCache = getEntryCache(); |
| | | final Entry cacheEntry = entryCache.getEntry(backend, entryID.longValue()); |
| | | if (cacheEntry != null) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the number of values for which the entry limit has been exceeded |
| | | * since the entry container was opened. |
| | | * @return The number of values for which the entry limit has been exceeded. |
| | | */ |
| | | public int getEntryLimitExceededCount() |
| | | { |
| | | int count = 0; |
| | | count += id2children.getEntryLimitExceededCount(); |
| | | count += id2subtree.getEntryLimitExceededCount(); |
| | | for (AttributeIndex index : attrIndexMap.values()) |
| | | { |
| | | count += index.getEntryLimitExceededCount(); |
| | | } |
| | | return count; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Get a list of the databases opened by the entryContainer. |
| | |
| | | * |
| | | * @return The container name for the base DN. |
| | | */ |
| | | public String getDatabasePrefix() |
| | | String getDatabasePrefix() |
| | | { |
| | | return databasePrefix; |
| | | } |
| | |
| | | * @param newBaseDN The new database prefix to use. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public void setDatabasePrefix(final String newBaseDN) throws StorageRuntimeException |
| | | void setDatabasePrefix(final String newBaseDN) throws StorageRuntimeException |
| | | { |
| | | final List<DatabaseContainer> databases = new ArrayList<DatabaseContainer>(); |
| | | listDatabases(databases); |
| | |
| | | * @param database The database to clear. |
| | | * @throws StorageRuntimeException if a JE database error occurs. |
| | | */ |
| | | public void clearDatabase(WriteableStorage txn, DatabaseContainer database) throws StorageRuntimeException |
| | | void clearDatabase(WriteableStorage txn, DatabaseContainer database) |
| | | throws StorageRuntimeException |
| | | { |
| | | database.close(); |
| | | try |
| | |
| | | } |
| | | |
| | | /** Get the exclusive lock. */ |
| | | public void lock() { |
| | | void lock() |
| | | { |
| | | exclusiveLock.lock(); |
| | | } |
| | | |
| | | /** Unlock the exclusive lock. */ |
| | | public void unlock() { |
| | | void unlock() |
| | | { |
| | | exclusiveLock.unlock(); |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * There are static methods to assign monotonically increasing entry IDs, |
| | | * starting from 1. |
| | | */ |
| | | public class EntryID implements Comparable<EntryID> |
| | | class EntryID implements Comparable<EntryID> |
| | | { |
| | | /** The identifier integer value. */ |
| | | private final long id; |
| | |
| | | * Create a new entry ID object from a given long value. |
| | | * @param id The long value of the ID. |
| | | */ |
| | | public EntryID(long id) |
| | | EntryID(long id) |
| | | { |
| | | this.id = id; |
| | | } |
| | |
| | | * Create a new entry ID object from a value in database format. |
| | | * @param value The database value of the ID. |
| | | */ |
| | | public EntryID(ByteString value) |
| | | EntryID(ByteString value) |
| | | { |
| | | this.value = value; |
| | | id = value.toLong(); |
| | |
| | | * Get the value of the entry ID as a long. |
| | | * @return The entry ID. |
| | | */ |
| | | public long longValue() |
| | | long longValue() |
| | | { |
| | | return id; |
| | | } |
| | |
| | | * Get the value of the ID in database format. |
| | | * @return The value of the ID in database format. |
| | | */ |
| | | public ByteString toByteString() |
| | | ByteString toByteString() |
| | | { |
| | | if (value == null) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * Represents a set of Entry IDs. It can represent a set where the IDs are |
| | | * not defined, for example when the index entry limit has been exceeded. |
| | | */ |
| | | public class EntryIDSet implements Iterable<EntryID> |
| | | class EntryIDSet implements Iterable<EntryID> |
| | | { |
| | | |
| | | /** |
| | |
| | | * |
| | | * @param size The undefined size for this set. |
| | | */ |
| | | public EntryIDSet(long size) |
| | | EntryIDSet(long size) |
| | | { |
| | | this.key = null; |
| | | this.undefinedSize = size; |
| | |
| | | * @param bytes |
| | | * The database value, or null if there are no entry IDs. |
| | | */ |
| | | public EntryIDSet(ByteSequence key, ByteString bytes) |
| | | EntryIDSet(ByteSequence key, ByteString bytes) |
| | | { |
| | | this.key = key; |
| | | |
| | |
| | | * duplicates should be eliminated. |
| | | * @return The union of the provided entry ID sets. |
| | | */ |
| | | public static EntryIDSet unionOfSets(ArrayList<EntryIDSet> sets, |
| | | static EntryIDSet unionOfSets(ArrayList<EntryIDSet> sets, |
| | | boolean allowDuplicates) |
| | | { |
| | | int count = 0; |
| | |
| | | * |
| | | * @param buffer The string is appended to this string builder. |
| | | */ |
| | | public void toString(StringBuilder buffer) |
| | | void toString(StringBuilder buffer) |
| | | { |
| | | if (!isDefined()) |
| | | { |
| | |
| | | * |
| | | * @return true if the set of IDs is defined. |
| | | */ |
| | | public boolean isDefined() |
| | | boolean isDefined() |
| | | { |
| | | return values != null; |
| | | } |
| | |
| | | * Get a database representation of this object. |
| | | * @return A database representation of this object as a byte array. |
| | | */ |
| | | public ByteString toByteString() |
| | | ByteString toByteString() |
| | | { |
| | | if (isDefined()) |
| | | { |
| | |
| | | * @return true if this set contains the given ID, |
| | | * or if the set is undefined. |
| | | */ |
| | | public boolean contains(EntryID entryID) |
| | | boolean contains(EntryID entryID) |
| | | { |
| | | if (values == null) |
| | | { |
| | |
| | | * |
| | | * @param that The set of IDs that are to be retained from this object. |
| | | */ |
| | | public void retainAll(EntryIDSet that) |
| | | void retainAll(EntryIDSet that) |
| | | { |
| | | if (!isDefined()) |
| | | { |
| | |
| | | * |
| | | * @param that The set of IDs to be deleted. It MUST be defined. |
| | | */ |
| | | public void deleteAll(EntryIDSet that) |
| | | void deleteAll(EntryIDSet that) |
| | | { |
| | | if(!that.isDefined()) |
| | | { |
| | |
| | | * |
| | | * @return An EntryID iterator. |
| | | */ |
| | | public Iterator<EntryID> iterator(EntryID begin) |
| | | Iterator<EntryID> iterator(EntryID begin) |
| | | { |
| | | if (values != null) |
| | | { |
| | |
| | | * This class provides a mechanism for sorting the contents of an entry ID set |
| | | * based on a given sort order. |
| | | */ |
| | | public class EntryIDSetSorter |
| | | class EntryIDSetSorter |
| | | { |
| | | /** |
| | | * Creates a new entry ID set which is a sorted representation of the provided |
| | |
| | | /** |
| | | * Export a JE backend to LDIF. |
| | | */ |
| | | public class ExportJob |
| | | class ExportJob |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | /** |
| | | * The requested LDIF export configuration. |
| | | */ |
| | | private LDIFExportConfig exportConfig; |
| | | private final LDIFExportConfig exportConfig; |
| | | |
| | | /** |
| | | * The number of milliseconds between job progress reports. |
| | | */ |
| | | private long progressInterval = 10000; |
| | | private final long progressInterval = 10000; |
| | | |
| | | /** |
| | | * The current number of entries exported. |
| | |
| | | * |
| | | * @param exportConfig The requested LDIF export configuration. |
| | | */ |
| | | public ExportJob(LDIFExportConfig exportConfig) |
| | | ExportJob(LDIFExportConfig exportConfig) |
| | | { |
| | | this.exportConfig = exportConfig; |
| | | } |
| | |
| | | * @throws LDIFException If an error occurs while trying to determine whether |
| | | * to write an entry. |
| | | */ |
| | | public void exportLDIF(RootContainer rootContainer) |
| | | void exportLDIF(RootContainer rootContainer) |
| | | throws IOException, LDIFException, StorageRuntimeException |
| | | { |
| | | List<DN> includeBranches = exportConfig.getIncludeBranches(); |
| | |
| | | /** |
| | | * This class reports progress of the export job at fixed intervals. |
| | | */ |
| | | class ProgressTask extends TimerTask |
| | | private class ProgressTask extends TimerTask |
| | | { |
| | | /** |
| | | * The number of entries that had been exported at the time of the |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | /** |
| | | * Implementation of an Indexer for the children index. |
| | | */ |
| | | public class ID2CIndexer extends Indexer |
| | | class ID2CIndexer extends Indexer |
| | | { |
| | | /** |
| | | * Create a new indexer for a children index. |
| | |
| | | public void indexEntry(Entry entry, Set<ByteString> addKeys, IndexingOptions options) |
| | | { |
| | | // The superior entry IDs are in the entry attachment. |
| | | @SuppressWarnings("unchecked") |
| | | ArrayList<EntryID> ids = (ArrayList<EntryID>) entry.getAttachment(); |
| | | |
| | | // Skip the entry's own ID. |
| | |
| | | * 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 |
| | | class ID2Entry extends DatabaseContainer |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | */ |
| | | private static final class EntryCodec |
| | | { |
| | | /** The ASN1 tag for the ByteString type. */ |
| | | private static final byte TAG_DATABASE_ENTRY = 0x60; |
| | | private static final int BUFFER_INIT_SIZE = 512; |
| | | |
| | | private final ByteStringBuilder encodedBuffer = new ByteStringBuilder(); |
| | |
| | | } |
| | | |
| | | private Entry decode(ByteString bytes, CompressedSchema compressedSchema) |
| | | throws DirectoryException, DecodeException, LDAPException, |
| | | DataFormatException, IOException |
| | | throws DirectoryException, DecodeException, IOException |
| | | { |
| | | // Get the format version. |
| | | byte formatVersion = bytes.byteAt(0); |
| | |
| | | try |
| | | { |
| | | // Then start the ASN1 sequence. |
| | | writer.writeStartSequence(JebFormat.TAG_DATABASE_ENTRY); |
| | | writer.writeStartSequence(TAG_DATABASE_ENTRY); |
| | | |
| | | if (dataConfig.isCompressed()) |
| | | { |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws IOException if an error occurs while reading the ASN1 sequence. |
| | | */ |
| | | public static Entry entryFromDatabase(ByteString bytes, |
| | | static Entry entryFromDatabase(ByteString bytes, |
| | | CompressedSchema compressedSchema) throws DirectoryException, |
| | | DecodeException, LDAPException, DataFormatException, IOException |
| | | { |
| | |
| | | * @param dataConfig The desired compression and encryption options for data |
| | | * stored in the entry database. |
| | | */ |
| | | public void setDataConfig(DataConfig dataConfig) |
| | | void setDataConfig(DataConfig dataConfig) |
| | | { |
| | | this.dataConfig = dataConfig; |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | /** |
| | | * Implementation of an Indexer for the subtree index. |
| | | */ |
| | | public class ID2SIndexer extends Indexer |
| | | class ID2SIndexer extends Indexer |
| | | { |
| | | /** |
| | | * Create a new indexer for a subtree index. |
| | |
| | | public void indexEntry(Entry entry, Set<ByteString> addKeys, IndexingOptions options) |
| | | { |
| | | // The superior entry IDs are in the entry attachment. |
| | | @SuppressWarnings("unchecked") |
| | | ArrayList<EntryID> ids = (ArrayList<EntryID>) entry.getAttachment(); |
| | | |
| | | // Skip the entry's own ID. |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | /** |
| | | * Iterator for a set of Entry IDs. It must return values in order of ID. |
| | | */ |
| | | public class IDSetIterator implements Iterator<EntryID> |
| | | class IDSetIterator implements Iterator<EntryID> |
| | | { |
| | | /** |
| | | * An array of ID values in order of ID. |
| | | */ |
| | | private long[] entryIDList; |
| | | private final long[] entryIDList; |
| | | |
| | | /** |
| | | * Current position of the iterator as an index into the array of IDs. |
| | |
| | | * Create a new iterator for a given array of entry IDs. |
| | | * @param entryIDList An array of IDs in order or ID. |
| | | */ |
| | | public IDSetIterator(long[] entryIDList) |
| | | IDSetIterator(long[] entryIDList) |
| | | { |
| | | this.entryIDList = entryIDList; |
| | | } |
| | |
| | | * @param begin The entry ID of the first entry that should be returned, or |
| | | * {@code null} if it should start at the beginning of the list. |
| | | */ |
| | | public IDSetIterator(long[] entryIDList, EntryID begin) |
| | | IDSetIterator(long[] entryIDList, EntryID begin) |
| | | { |
| | | this.entryIDList = entryIDList; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | private void initializeSuffixes(WriteableStorage txn) throws StorageRuntimeException, ConfigException, |
| | | InitializationException |
| | | private void initializeSuffixes(WriteableStorage txn) throws StorageRuntimeException, |
| | | ConfigException |
| | | { |
| | | for (EntryContainer ec : rootContainer.getEntryContainers()) |
| | | { |
| | |
| | | } |
| | | |
| | | private Suffix getSuffix(WriteableStorage txn, EntryContainer entryContainer) |
| | | throws ConfigException, InitializationException |
| | | throws ConfigException |
| | | { |
| | | DN baseDN = entryContainer.getBaseDN(); |
| | | EntryContainer sourceEntryContainer = null; |
| | |
| | | |
| | | /** |
| | | * Print start message. |
| | | * |
| | | * @throws StorageRuntimeException |
| | | * If an database error occurred. |
| | | */ |
| | | public void printStartMessage(WriteableStorage txn) throws StorageRuntimeException |
| | | void printStartMessage(WriteableStorage txn) throws StorageRuntimeException |
| | | { |
| | | this.txn = txn; |
| | | totalEntries = suffix.getID2Entry().getRecordCount(txn); |
| | |
| | | * |
| | | * @return Entry's suffix instance; |
| | | */ |
| | | public Suffix getSuffix() |
| | | private Suffix getSuffix() |
| | | { |
| | | return suffix; |
| | | } |
| | |
| | | * |
| | | * @return The entry ID associated with the entry. |
| | | */ |
| | | public EntryID getEntryID() |
| | | private EntryID getEntryID() |
| | | { |
| | | return entryID; |
| | | } |
| | |
| | | * |
| | | * @return The attribute type. |
| | | */ |
| | | public AttributeType getAttributeType() |
| | | private AttributeType getAttributeType() |
| | | { |
| | | return attributeType; |
| | | } |
| | |
| | | * |
| | | * @return The index type. |
| | | */ |
| | | public ImportIndexType getIndexType() |
| | | private ImportIndexType getIndexType() |
| | | { |
| | | return indexType; |
| | | } |
| | |
| | | * |
| | | * @return The index key name. |
| | | */ |
| | | public String getName() |
| | | private String getName() |
| | | { |
| | | return attributeType.getPrimaryName() + "." |
| | | + StaticUtils.toLowerCase(indexType.name()); |
| | |
| | | * |
| | | * @return The entry limit. |
| | | */ |
| | | public int getEntryLimit() |
| | | private int getEntryLimit() |
| | | { |
| | | return entryLimit; |
| | | } |
| | |
| | | * normalized form of an attribute value (or fragment of a value) appearing |
| | | * in the entry. |
| | | */ |
| | | public class Index extends DatabaseContainer |
| | | class Index extends DatabaseContainer |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | /** The indexer object to construct index keys from LDAP attribute values. */ |
| | | public Indexer indexer; |
| | | Indexer indexer; |
| | | |
| | | /** The limit on the number of entry IDs that may be indexed by one key. */ |
| | | private int indexEntryLimit; |
| | |
| | | * @param keyBytes The index key bytes. |
| | | * @param entryID The entry ID. |
| | | */ |
| | | void insertID(IndexBuffer buffer, ByteString keyBytes, EntryID entryID) |
| | | final void insertID(IndexBuffer buffer, ByteString keyBytes, EntryID entryID) |
| | | { |
| | | getBufferedIndexValues(buffer, keyBytes).addEntryID(keyBytes, entryID); |
| | | } |
| | |
| | | * @param importIdSet The import ID set to delete. |
| | | * @throws StorageRuntimeException If a database error occurs. |
| | | */ |
| | | void delete(WriteableStorage txn, ByteSequence key, ImportIDSet importIdSet) throws StorageRuntimeException { |
| | | final void delete(WriteableStorage txn, ByteSequence key, ImportIDSet importIdSet) |
| | | throws StorageRuntimeException |
| | | { |
| | | ByteString value = read(txn, key, false); |
| | | if (value != null) { |
| | | newImportIDSet.clear(); |
| | |
| | | * @param importIdSet The set of import IDs. |
| | | * @throws StorageRuntimeException If a database error occurs. |
| | | */ |
| | | void insert(WriteableStorage txn, ByteSequence key, ImportIDSet importIdSet) throws StorageRuntimeException { |
| | | final void insert(WriteableStorage txn, ByteSequence key, ImportIDSet importIdSet) |
| | | throws StorageRuntimeException |
| | | { |
| | | ByteString value = read(txn, key, false); |
| | | if(value != null) { |
| | | newImportIDSet.clear(); |
| | |
| | | * @param keyBytes The index key bytes. |
| | | * @param entryID The entry ID. |
| | | */ |
| | | void removeID(IndexBuffer buffer, ByteString keyBytes, EntryID entryID) |
| | | final void removeID(IndexBuffer buffer, ByteString keyBytes, EntryID entryID) |
| | | { |
| | | getBufferedIndexValues(buffer, keyBytes).deleteEntryID(keyBytes, entryID); |
| | | } |
| | |
| | | * |
| | | * @param indexer The indexer to set |
| | | */ |
| | | public void setIndexer(Indexer indexer) |
| | | final void setIndexer(Indexer indexer) |
| | | { |
| | | this.indexer = indexer; |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * the same transaction. The transaction may be null if it is known |
| | | * that there are no other concurrent updates to the index. |
| | | */ |
| | | public class IndexBuffer |
| | | class IndexBuffer |
| | | { |
| | | private final EntryContainer entryContainer; |
| | | |
| | |
| | | * @param entryContainer The database entryContainer using this |
| | | * index buffer. |
| | | */ |
| | | public IndexBuffer(EntryContainer entryContainer) |
| | | IndexBuffer(EntryContainer entryContainer) |
| | | { |
| | | this.entryContainer = entryContainer; |
| | | } |
| | |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | public void flush(WriteableStorage txn) throws StorageRuntimeException, DirectoryException |
| | | void flush(WriteableStorage txn) throws StorageRuntimeException, DirectoryException |
| | | { |
| | | /* |
| | | * FIXME: this seems like a surprising way to update the indexes. Why not |
| | |
| | | * An index filter is used to apply a search operation to a set of indexes |
| | | * to generate a set of candidate entries. |
| | | */ |
| | | public class IndexFilter |
| | | class IndexFilter |
| | | { |
| | | /** |
| | | * Stop processing the filter against the indexes when the |
| | | * number of candidates is smaller than this value. |
| | | */ |
| | | public static final int FILTER_CANDIDATE_THRESHOLD = 10; |
| | | static final int FILTER_CANDIDATE_THRESHOLD = 10; |
| | | |
| | | /** The entry container holding the attribute indexes. */ |
| | | private final EntryContainer entryContainer; |
| | |
| | | * which will help determine how the indexes contributed |
| | | * to this search. |
| | | */ |
| | | public IndexFilter(EntryContainer entryContainer, ReadableStorage txn, SearchOperation searchOp, |
| | | IndexFilter(EntryContainer entryContainer, ReadableStorage txn, SearchOperation searchOp, |
| | | StringBuilder debugBuilder, DatabaseEnvironmentMonitor monitor) |
| | | { |
| | | this.entryContainer = entryContainer; |
| | |
| | | * |
| | | * @return A set of entry IDs representing candidate entries. |
| | | */ |
| | | public EntryIDSet evaluate() |
| | | EntryIDSet evaluate() |
| | | { |
| | | if (buffer != null) |
| | | { |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | mayInstantiate = false, |
| | | mayExtend = true, |
| | | mayInvoke = false) |
| | | public abstract class IndexQuery |
| | | abstract class IndexQuery |
| | | { |
| | | /** |
| | | * Evaluates the index query and returns the EntryIDSet. |
| | |
| | | * A collection of IndexQuery objects. |
| | | * @return An IntersectionIndexQuery object. |
| | | */ |
| | | public static IndexQuery createIntersectionIndexQuery( |
| | | static IndexQuery createIntersectionIndexQuery( |
| | | Collection<IndexQuery> subIndexQueries) |
| | | { |
| | | return new IntersectionIndexQuery(subIndexQueries); |
| | |
| | | * Collection of IndexQuery objects. |
| | | * @return A UnionIndexQuery object. |
| | | */ |
| | | public static IndexQuery createUnionIndexQuery( |
| | | static IndexQuery createUnionIndexQuery( |
| | | Collection<IndexQuery> subIndexQueries) |
| | | { |
| | | return new UnionIndexQuery(subIndexQueries); |
| | |
| | | * |
| | | * @return A NullIndexQuery object. |
| | | */ |
| | | public static IndexQuery createNullIndexQuery() |
| | | static IndexQuery createNullIndexQuery() |
| | | { |
| | | return new NullIndexQuery(); |
| | | } |
| | |
| | | * |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * This class is an implementation of IndexQueryFactory which creates |
| | | * IndexQuery objects as part of the query of the JEB index. |
| | | */ |
| | | public final class IndexQueryFactoryImpl implements IndexQueryFactory<IndexQuery> |
| | | final class IndexQueryFactoryImpl implements IndexQueryFactory<IndexQuery> |
| | | { |
| | | |
| | | private static final String PRESENCE_INDEX_KEY = "presence"; |
| | |
| | | * @param attributeIndex |
| | | * The targeted attribute index |
| | | */ |
| | | public IndexQueryFactoryImpl(ReadableStorage txn, AttributeIndex attributeIndex) |
| | | IndexQueryFactoryImpl(ReadableStorage txn, AttributeIndex attributeIndex) |
| | | { |
| | | this.txn = txn; |
| | | this.attributeIndex = attributeIndex; |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2012-2014 ForgeRock AS. |
| | | * Portions copyright 2012-2015 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * This class attempts to abstract the generation and comparison of keys |
| | | * for an index. It is subclassed for the specific type of indexing. |
| | | */ |
| | | public abstract class Indexer |
| | | abstract class Indexer |
| | | { |
| | | /** |
| | | * Generate the set of index keys for an entry. |
| | |
| | | * This class provides a compressed schema implementation whose definitions are |
| | | * stored in a Berkeley DB JE database. |
| | | */ |
| | | public final class JECompressedSchema extends CompressedSchema |
| | | final class JECompressedSchema extends CompressedSchema |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | * If an error occurs while loading and processing the compressed |
| | | * schema definitions. |
| | | */ |
| | | public JECompressedSchema(final Storage storage, WriteableStorage txn) |
| | | JECompressedSchema(final Storage storage, WriteableStorage txn) |
| | | throws StorageRuntimeException, InitializationException |
| | | { |
| | | this.storage = storage; |
| | |
| | | { |
| | | |
| | | /** The format version used by this class to encode and decode a ByteString. */ |
| | | public static final byte FORMAT_VERSION = 0x01; |
| | | /** The ASN1 tag for the ByteString type. */ |
| | | public static final byte TAG_DATABASE_ENTRY = 0x60; |
| | | /** The ASN1 tag for the DirectoryServerEntry type. */ |
| | | public static final byte TAG_DIRECTORY_SERVER_ENTRY = 0x61; |
| | | static final byte FORMAT_VERSION = 0x01; |
| | | |
| | | /** |
| | | * Find the length of bytes that represents the superior DN of the given DN |
| | |
| | | * @return The length of the superior DN or -1 if the given dn is the root DN |
| | | * or 0 if the superior DN is removed. |
| | | */ |
| | | public static int findDNKeyParent(ByteSequence dnKey) |
| | | static int findDNKeyParent(ByteSequence dnKey) |
| | | { |
| | | if (dnKey.length() == 0) |
| | | { |
| | |
| | | * representation. |
| | | * @return A ByteString containing the key. |
| | | */ |
| | | public static ByteString dnToDNKey(DN dn, int prefixRDNs) |
| | | static ByteString dnToDNKey(DN dn, int prefixRDNs) |
| | | { |
| | | final ByteStringBuilder builder = new ByteStringBuilder(); |
| | | final int startSize = dn.size() - prefixRDNs - 1; |
| | |
| | | /** |
| | | * An implementation of an Indexer for attribute presence. |
| | | */ |
| | | public class PresenceIndexer extends Indexer |
| | | class PresenceIndexer extends Indexer |
| | | { |
| | | /** The key bytes used for the presence index. */ |
| | | static final byte[] presenceKeyBytes = "+".getBytes(); |
| | | private static final byte[] presenceKeyBytes = "+".getBytes(); |
| | | |
| | | /** The key bytes used for the presence index as a {@link ByteString}. */ |
| | | static final ByteString presenceKey = ByteString.wrap(presenceKeyBytes); |
| | | |
| | | /** The attribute type for which this instance will generate index keys. */ |
| | | private AttributeType attributeType; |
| | | private final AttributeType attributeType; |
| | | |
| | | /** |
| | | * Create a new attribute presence indexer. |
| | | * @param attributeType The attribute type for which the indexer |
| | | * is required. |
| | | */ |
| | | public PresenceIndexer(AttributeType attributeType) |
| | | PresenceIndexer(AttributeType attributeType) |
| | | { |
| | | this.attributeType = attributeType; |
| | | } |
| | |
| | | /** The backend to which this entry root container belongs. */ |
| | | private final BackendImpl backend; |
| | | /** The backend configuration. */ |
| | | private PluggableBackendCfg config; |
| | | private final PluggableBackendCfg config; |
| | | /** The database environment monitor for this JE environment. */ |
| | | private DatabaseEnvironmentMonitor monitor; |
| | | |
| | |
| | | * |
| | | * @return The compressed schema manager for this backend. |
| | | */ |
| | | public CompressedSchema getCompressedSchema() |
| | | CompressedSchema getCompressedSchema() |
| | | { |
| | | return compressedSchema; |
| | | } |
| | |
| | | * |
| | | * @return The DatabaseEnvironmentMonitor object. |
| | | */ |
| | | public DatabaseEnvironmentMonitor getMonitorProvider() |
| | | DatabaseEnvironmentMonitor getMonitorProvider() |
| | | { |
| | | if (monitor == null) |
| | | { |
| | |
| | | * |
| | | * @return The set of DNs this root container stores. |
| | | */ |
| | | public Set<DN> getBaseDNs() |
| | | Set<DN> getBaseDNs() |
| | | { |
| | | return entryContainers.keySet(); |
| | | } |
| | |
| | | * |
| | | * @return The backend configuration used by this root container. |
| | | */ |
| | | public PluggableBackendCfg getConfiguration() |
| | | PluggableBackendCfg getConfiguration() |
| | | { |
| | | return config; |
| | | } |
| | |
| | | * @throws StorageRuntimeException |
| | | * If an error occurs while retrieving the entry count. |
| | | */ |
| | | public long getEntryCount() throws StorageRuntimeException |
| | | long getEntryCount() throws StorageRuntimeException |
| | | { |
| | | try |
| | | { |
| | |
| | | * |
| | | * @return The assigned entry ID. |
| | | */ |
| | | public EntryID getNextEntryID() |
| | | EntryID getNextEntryID() |
| | | { |
| | | return new EntryID(nextid.getAndIncrement()); |
| | | } |
| | | |
| | | /** |
| | | * Return the lowest entry ID assigned. |
| | | * |
| | | * @return The lowest entry ID assigned. |
| | | */ |
| | | public Long getLowestEntryID() |
| | | { |
| | | return 1L; |
| | | } |
| | | |
| | | /** |
| | | * Resets the next entry ID counter to zero. This should only be used after |
| | | * clearing all databases. |
| | | */ |
| | |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014 ForgeRock AS |
| | | * Portions Copyright 2014-2015 ForgeRock AS |
| | | */ |
| | | package org.opends.server.backends.pluggable; |
| | | |
| | |
| | | * <p> |
| | | * FIXME: replace with the SDK's SortKey? |
| | | */ |
| | | public class SortValues |
| | | class SortValues |
| | | implements Comparable<SortValues> |
| | | { |
| | | /** The set of sort keys (attribute values) in this sort order. */ |
| | | private ByteString[] values; |
| | | private final ByteString[] values; |
| | | /** |
| | | * The types of sort keys. |
| | | * |
| | | * @see #values |
| | | */ |
| | | private AttributeType[] types; |
| | | private final AttributeType[] types; |
| | | |
| | | /** The entry ID for the entry associated with this sort values. */ |
| | | private EntryID entryID; |
| | | private final EntryID entryID; |
| | | |
| | | /** The sort order for this set of sort values. */ |
| | | private SortOrder sortOrder; |
| | | private final SortOrder sortOrder; |
| | | |
| | | |
| | | |
| | |
| | | * @param values The attribute values for this sort values. |
| | | * @param sortOrder The sort order to use to obtain the necessary values. |
| | | */ |
| | | public SortValues(EntryID entryID, ByteString[] values, |
| | | SortValues(EntryID entryID, ByteString[] values, |
| | | SortOrder sortOrder) |
| | | { |
| | | this.entryID = entryID; |
| | |
| | | * sorting. |
| | | * @param sortOrder The sort order to use to obtain the necessary values. |
| | | */ |
| | | public SortValues(EntryID entryID, Entry entry, SortOrder sortOrder) |
| | | SortValues(EntryID entryID, Entry entry, SortOrder sortOrder) |
| | | { |
| | | this.entryID = entryID; |
| | | this.sortOrder = sortOrder; |
| | |
| | | * is equal to the first sort value, or a positive value if the |
| | | * provided assertion value should come after the first sort value. |
| | | */ |
| | | public int compareTo(ByteString assertionValue) |
| | | int compareTo(ByteString assertionValue) |
| | | { |
| | | SortKey sortKey = sortOrder.getSortKeys()[0]; |
| | | return sortKey.compareValues(values[0], assertionValue); |
| | |
| | | * |
| | | * @param buffer The buffer to which the information should be appended. |
| | | */ |
| | | public void toString(StringBuilder buffer) |
| | | private void toString(StringBuilder buffer) |
| | | { |
| | | buffer.append("SortValues("); |
| | | |
| | |
| | | * |
| | | * @return The array of attribute values for this sort values. |
| | | */ |
| | | public ByteString[] getValues() |
| | | ByteString[] getValues() |
| | | { |
| | | return values; |
| | | } |
| | |
| | | * |
| | | * @return The array of type of the attribute values for this sort values. |
| | | */ |
| | | public AttributeType[] getTypes() |
| | | AttributeType[] getTypes() |
| | | { |
| | | return types; |
| | | } |
| | |
| | | * |
| | | * @return The entry ID for this sort values. |
| | | */ |
| | | public long getEntryID() |
| | | long getEntryID() |
| | | { |
| | | return entryID.longValue(); |
| | | } |
| | |
| | | /** |
| | | * This class represents a partial sorted set of sorted entries in a VLV index. |
| | | */ |
| | | public class SortValuesSet |
| | | class SortValuesSet |
| | | { |
| | | private long[] entryIDs; |
| | | private int[] valuesBytesOffsets; |
| | |
| | | * |
| | | * @param vlvIndex The VLV index using this set. |
| | | */ |
| | | public SortValuesSet(VLVIndex vlvIndex) |
| | | SortValuesSet(VLVIndex vlvIndex) |
| | | { |
| | | this(vlvIndex, ByteString.empty(), null, null, null); |
| | | } |
| | |
| | | * @param value The bytes to decode and construct this set. |
| | | * @param vlvIndex The VLV index using this set. |
| | | */ |
| | | public SortValuesSet(ByteString key, ByteString value, VLVIndex vlvIndex) |
| | | SortValuesSet(ByteString key, ByteString value, VLVIndex vlvIndex) |
| | | { |
| | | this.key = key; |
| | | this.vlvIndex = vlvIndex; |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public boolean add(long entryID, ByteString[] values, AttributeType[] types) |
| | | private boolean add(long entryID, ByteString[] values, AttributeType[] types) |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | if(values == null) |
| | |
| | | * @param splitLength The size of the new set. |
| | | * @return The split set. |
| | | */ |
| | | public SortValuesSet split(int splitLength) |
| | | SortValuesSet split(int splitLength) |
| | | { |
| | | if(valuesBytesOffsets == null) |
| | | { |
| | |
| | | * @return The encoded bytes representing this set or null if |
| | | * this set is empty. |
| | | */ |
| | | public ByteString toByteString() |
| | | ByteString toByteString() |
| | | { |
| | | if(size() == 0) |
| | | { |
| | |
| | | * @param bytes The encoded bytes of a SortValuesSet to decode the IDs from. |
| | | * @return The decoded IDs in the provided encoded set. |
| | | */ |
| | | public static long[] getEncodedIDs(ByteString bytes) |
| | | static long[] getEncodedIDs(ByteString bytes) |
| | | { |
| | | final ByteSequenceReader reader = bytes.asReader(); |
| | | final int length = reader.getInt(); |
| | |
| | | * |
| | | * @return The size of this set. |
| | | */ |
| | | public int size() |
| | | int size() |
| | | { |
| | | if(entryIDs == null) |
| | | { |
| | |
| | | * |
| | | * @return The entry IDs in this set. |
| | | */ |
| | | public long[] getEntryIDs() |
| | | long[] getEntryIDs() |
| | | { |
| | | return entryIDs; |
| | | } |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public ByteString getKeyBytes() |
| | | ByteString getKeyBytes() |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | if(entryIDs == null || entryIDs.length == 0) |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public SortValues getKeySortValues() |
| | | SortValues getKeySortValues() |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | if(entryIDs == null || entryIDs.length == 0) |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public SortValues getSortValues(int index) throws StorageRuntimeException, DirectoryException |
| | | SortValues getSortValues(int index) throws StorageRuntimeException, DirectoryException |
| | | { |
| | | if(entryIDs == null || entryIDs.length == 0) |
| | | { |
| | |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public ByteString getValue(int index) |
| | | ByteString getValue(int index) |
| | | throws StorageRuntimeException, DirectoryException |
| | | { |
| | | if(valuesBytesOffsets == null) |
| | |
| | | * This class is responsible for storing the configuration state of |
| | | * the JE backend for a particular suffix. |
| | | */ |
| | | public class State extends DatabaseContainer |
| | | class State extends DatabaseContainer |
| | | { |
| | | private static final ByteString falseBytes = ByteString.wrap(new byte[] { 0x00 }); |
| | | private static final ByteString trueBytes = ByteString.wrap(new byte[] { 0x01 }); |
| | |
| | | * @return The trusted state of the index in the database. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public boolean getIndexTrustState(ReadableStorage txn, DatabaseContainer index) |
| | | boolean getIndexTrustState(ReadableStorage txn, DatabaseContainer index) |
| | | throws StorageRuntimeException |
| | | { |
| | | ByteString key = keyForIndex(index); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Get the parent DN of the last entry added to a suffix. |
| | | * |
| | | * @return The parent DN of the last entry added. |
| | | */ |
| | | public DN getParentDN() |
| | | { |
| | | return parentDN; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Set the parent DN of the last entry added to a suffix. |
| | | * |
| | | * @param parentDN The parent DN to save. |
| | | */ |
| | | public void setParentDN(DN parentDN) |
| | | { |
| | | this.parentDN = parentDN; |
| | | } |
| | | |
| | | /** |
| | | * Return a src entry container. |
| | | * |
| | | * @return The src entry container. |
| | |
| | | * attribute value is bigger then the previous key but smaller or equal |
| | | * to its own key. |
| | | */ |
| | | public class VLVIndex extends DatabaseContainer |
| | | class VLVIndex extends DatabaseContainer |
| | | implements ConfigurationChangeListener<BackendVLVIndexCfg> |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | |
| | | * otherwise. |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | */ |
| | | public synchronized void setTrusted(WriteableStorage txn, boolean trusted) |
| | | synchronized void setTrusted(WriteableStorage txn, boolean trusted) |
| | | throws StorageRuntimeException |
| | | { |
| | | this.trusted = trusted; |
| | |
| | | * Return true iff this index is trusted. |
| | | * @return the trusted state of this index |
| | | */ |
| | | public boolean isTrusted() |
| | | boolean isTrusted() |
| | | { |
| | | return trusted; |
| | | } |
| | |
| | | * @return The encoded bytes. |
| | | * @throws DirectoryException If a Directory Server error occurs. |
| | | */ |
| | | ByteString encodeKey(long entryID, ByteString[] values, AttributeType[] types) |
| | | private ByteString encodeKey(long entryID, ByteString[] values, AttributeType[] types) |
| | | throws DirectoryException |
| | | { |
| | | try |
| | |
| | | import org.opends.server.util.StaticUtils; |
| | | |
| | | /** This class is used to run an index verification process on the backend. */ |
| | | public class VerifyJob |
| | | class VerifyJob |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | |
| | | * |
| | | * @param verifyConfig The verify configuration. |
| | | */ |
| | | public VerifyJob(VerifyConfig verifyConfig) |
| | | VerifyJob(VerifyConfig verifyConfig) |
| | | { |
| | | this.verifyConfig = verifyConfig; |
| | | } |
| | |
| | | * @throws StorageRuntimeException If an error occurs in the JE database. |
| | | * @throws DirectoryException If an error occurs while verifying the backend. |
| | | */ |
| | | public long verifyBackend(final RootContainer rootContainer) throws StorageRuntimeException, DirectoryException |
| | | long verifyBackend(final RootContainer rootContainer) throws StorageRuntimeException, |
| | | DirectoryException |
| | | { |
| | | try |
| | | { |
| | |
| | | * @param key |
| | | * the record's key |
| | | * @return the record's value, or {@code null} if none exists |
| | | * @deprecated use {@link #update(TreeName, ByteSequence, UpdateFunction)} instead |
| | | * @deprecated use {@link WriteableStorage#update(TreeName, ByteSequence, UpdateFunction)} instead |
| | | */ |
| | | @Deprecated |
| | | ByteString getRMW(TreeName treeName, ByteSequence key); |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // For the purposes of this method, this is a local backend. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isLocal() |
| | | { |
| | | // The configuration information will always be local. |
| | | return true; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isIndexed(AttributeType attributeType, IndexType indexType) |
| | | { |
| | | // All searches in this backend will always be considered indexed. |
| | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isLocal} method for the provided backend. |
| | | * |
| | | * @param b The backend to test. |
| | | */ |
| | | @Test(dataProvider = "backends") |
| | | public void testIsLocal(Backend<?> b) |
| | | { |
| | | b.isLocal(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getSupportedControls} method for the provided backend. |
| | | * |
| | | * @param b The backend to test. |
| | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code supportsFeature} method for the provided backend. |
| | | * |
| | | * @param b The backend to test. |
| | | */ |
| | | @Test(dataProvider = "backends") |
| | | public void testSupportsFeature(Backend<?> b) |
| | | { |
| | | assertFalse(b.supportsFeature("1.2.3.4")); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code supportsLDIFExport} method for the provided backend. |
| | | * |
| | | * @param b The backend to test. |
| | |
| | | { |
| | | LDIFBackend b = getLDIFBackend(); |
| | | assertTrue(b.getEntryCount() > 0); |
| | | assertTrue(b.isLocal()); |
| | | assertFalse(b.supports(BackendOperation.BACKUP)); |
| | | |
| | | try |
| | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code isLocal} method to ensure that it is considered local. |
| | | */ |
| | | @Test |
| | | public void testIsLocal() |
| | | { |
| | | assertTrue(schemaBackend.isLocal()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Tests the {@code getEntry} method to ensure that it is able to retrieve |
| | | * the schema entry if it is given a valid entry DN. |
| | | * |