/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. * */ package com.sleepycat.je; import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import com.sleepycat.je.dbi.DatabaseImpl; import com.sleepycat.je.trigger.ReplicatedDatabaseTrigger; import com.sleepycat.je.trigger.PersistentTrigger; import com.sleepycat.je.trigger.Trigger; /** *
Specifies the attributes of a database.
* *There are two groups of database attributes: per-database handle * attributes, and database-wide attributes. An attribute may be * persistent/transient or mutable/immutable:
* *Scope | *Mutable | *Persistent | *Attribute | *
Database-wide attribute | *True | *True | *{@link DatabaseConfig#getBtreeComparator() btree comparator} * {@link DatabaseConfig#getDuplicateComparator() duplicate comparator} * {@link DatabaseConfig#getKeyPrefixing() key prefixing} * {@link DatabaseConfig#getNodeMaxEntries() nodeMaxEntries} * * |
True | *False | *{@link DatabaseConfig#getDeferredWrite() deferred write} * {@link DatabaseConfig#getTransactional() transactional} |
* |
False | *True | *
* {@link DatabaseConfig#getSortedDuplicates() sorted duplicates} * |
* |
False | *False | *{@link DatabaseConfig#getTemporary() temporary} | *|
Per-database handle attributes | *False | *False | *{@link DatabaseConfig#getAllowCreate() allow create} * {@link DatabaseConfig#getExclusiveCreate() exclusive create} * {@link DatabaseConfig#getReadOnly() read only} * {@link DatabaseConfig#getUseExistingConfig() use existing config} * |
*
Persistent attributes will be saved in the log and remain in effect * every time the environment is reopened. Transient attributes only remain * in effect until:
* *This method may be called at any time during the life of the * application.
* * @return true if the {@link com.sleepycat.je.Environment#openDatabase * Environment.openDatabase} method is configured to create the database * if it does not already exist. */ public boolean getAllowCreate() { return allowCreate; } /** * Configure the {@link com.sleepycat.je.Environment#openDatabase * Environment.openDatabase} method to fail if the database already exists. * *The exclusiveCreate mode is only meaningful if specified with the * allowCreate mode.
* * @param exclusiveCreate If true, configure the {@link * com.sleepycat.je.Environment#openDatabase Environment.openDatabase} * method to fail if the database already exists. * * @return this */ public DatabaseConfig setExclusiveCreate(boolean exclusiveCreate) { setExclusiveCreateVoid(exclusiveCreate); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setExclusiveCreateVoid(boolean exclusiveCreate) { this.exclusiveCreate = exclusiveCreate; } /** * Returns true if the {@link com.sleepycat.je.Environment#openDatabase * Environment.openDatabase} method is configured to fail if the database * already exists. * *This method may be called at any time during the life of the * application.
* * @return true if the {@link com.sleepycat.je.Environment#openDatabase * Environment.openDatabase} method is configured to fail if the database * already exists. */ public boolean getExclusiveCreate() { return exclusiveCreate; } /** * Configures the database to support records with duplicate keys. * *When duplicate keys are configured for a database, key prefixing is * also implicitly configured. Without key prefixing, databases with * duplicates would store keys inefficiently. Key prefixing is therefore * mandatory for databases with duplicates.
* *Although two records may have the same key, they may not also have * the same data item. Two identical records, that have the same key and * data, may not be stored in a database.
* *The ordering of duplicates in the database is determined by the * duplicate comparison function. See {@link #setDuplicateComparator}. If * the application does not specify a duplicate comparison function, a * default lexical comparison will be used.
* *If a primary database is to be associated with one or more secondary * databases, it may not be configured for duplicates.
* *Calling this method affects the database, including all threads of * control accessing the database.
* *If the database already exists when the database is opened, any * database configuration specified by this method must be the same as the * existing database or an error will be returned.
* * @param sortedDuplicates If true, configure the database to support * duplicate data items. A value of false is illegal to this method, that * is, once set, the configuration cannot be cleared. * * @return this */ public DatabaseConfig setSortedDuplicates(boolean sortedDuplicates) { setSortedDuplicatesVoid(sortedDuplicates); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setSortedDuplicatesVoid(boolean sortedDuplicates) { this.sortedDuplicates = sortedDuplicates; if (sortedDuplicates) { setKeyPrefixingVoid(true); } } /** * Returns true if the database is configured to support records with * duplicate keys. * *This method may be called at any time during the life of the * application.
* * @return true if the database is configured to support records with * duplicate keys. */ public boolean getSortedDuplicates() { return sortedDuplicates; } /** * Returns the key prefixing configuration. Note that key prefixing is * always enabled for a database with duplicates configured. * * @return true if key prefixing has been enabled in this database. */ public boolean getKeyPrefixing() { return keyPrefixing; } /** * Configure the database to support key prefixing. Key prefixing causes * the representation of keys in the b-tree internal nodes to be split * between the common prefix of all keys and the suffixes. Using this * may result in a more space-efficient representation in both the * in-memory and on-disk formats, but at some possible performance cost. * *When duplicate keys are configured for a database, key prefixing is * also implicitly configured. Without key prefixing, databases with * duplicates would store keys inefficiently. Key prefixing is therefore * mandatory for databases with duplicates.
* * @param keyPrefixing If true, enables keyPrefixing for the * database. * * @return this * * @throws IllegalStateException if the keyPrefixing argument is false and * {@link #setSortedDuplicates} has been called to configure duplicates. * Key prefixing is therefore mandatory for databases with duplicates. * */ public DatabaseConfig setKeyPrefixing(boolean keyPrefixing) { setKeyPrefixingVoid(keyPrefixing); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setKeyPrefixingVoid(boolean keyPrefixing) { if (!keyPrefixing && sortedDuplicates) { throw new IllegalStateException ("Key prefixing is mandatory for databases with duplicates"); } this.keyPrefixing = keyPrefixing; } /** * Encloses the database open within a transaction. * *If the call succeeds, the open operation will be recoverable. If the * call fails, no database will have been created.
* *All future operations on this database, which are not explicitly * enclosed in a transaction by the application, will be enclosed in in a * transaction within the library.
* * @param transactional If true, enclose the database open within a * transaction. * * @return this */ public DatabaseConfig setTransactional(boolean transactional) { setTransactionalVoid(transactional); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setTransactionalVoid(boolean transactional) { this.transactional = transactional; } /** * Returns true if the database open is enclosed within a transaction. * *This method may be called at any time during the life of the * application.
* * @return true if the database open is enclosed within a transaction. */ public boolean getTransactional() { return transactional; } /** * Configures the database in read-only mode. * *Any attempt to modify items in the database will fail, regardless of * the actual permissions of any underlying files.
* * @param readOnly If true, configure the database in read-only mode. * * @return this */ public DatabaseConfig setReadOnly(boolean readOnly) { setReadOnlyVoid(readOnly); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setReadOnlyVoid(boolean readOnly) { this.readOnly = readOnly; } /** * Returns true if the database is configured in read-only mode. * *This method may be called at any time during the life of the * application.
* * @return true if the database is configured in read-only mode. */ public boolean getReadOnly() { return readOnly; } /** * Configures the {@link com.sleepycat.je.Environment#openDatabase * Environment.openDatabase} method to have a B+Tree fanout of * nodeMaxEntries. * *The nodeMaxEntries parameter is only meaningful if specified with the * allowCreate mode. See {@link EnvironmentConfig#NODE_MAX_ENTRIES} for the * valid value range, and the default value.
* * @param nodeMaxEntries The maximum children per B+Tree node. * * @return this */ public DatabaseConfig setNodeMaxEntries(int nodeMaxEntries) { setNodeMaxEntriesVoid(nodeMaxEntries); return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setNodeMaxEntriesVoid(int nodeMaxEntries) { this.nodeMaxEntries = nodeMaxEntries; } /** * @deprecated this property no longer has any effect; {@link * #setNodeMaxEntries} should be used instead. */ public DatabaseConfig setNodeMaxDupTreeEntries(int nodeMaxDupTreeEntries) { return this; } /** * @hidden * The void return setter for use by Bean editors. */ public void setNodeMaxDupTreeEntriesVoid(int nodeMaxDupTreeEntries) { } /** * Returns the maximum number of children a B+Tree node can have. * *This method may be called at any time during the life of the * application.
* * @return The maximum number of children a B+Tree node can have. */ public int getNodeMaxEntries() { return nodeMaxEntries; } /** * @deprecated this property no longer has any effect and zero is always * returned; {@link #getNodeMaxEntries} should be used instead. */ public int getNodeMaxDupTreeEntries() { return 0; } /** * By default, a byte by byte lexicographic comparison is used for btree * keys. To customize the comparison, supply a different Comparator. * *Note that there are two ways to set the comparator: by specifying the * class or by specifying a serializable object. This method is used to * specify a serializable object. The comparator class must implement * java.util.Comparator and must be serializable. JE will serialize the * Comparator and deserialize it when subsequently opening the * database.
* *If a comparator needs to be initialized before it is used or needs * access to the environment's ClassLoader property, it may implement the * {@link DatabaseComparator} interface.
* *The Comparator.compare() method is passed the byte arrays that are * stored in the database. If you know how your data is organized in the * byte array, then you can write a comparison routine that directly * examines the contents of the arrays. Otherwise, you have to reconstruct * your original objects, and then perform the comparison. See the Getting Started Guide for examples.
* *WARNING: There are several special considerations that must * be taken into account when implementing a comparator.
*
A special type of comparator is a partial comparator, which * compares a proper subset (not all bytes) of the key. A partial * comparator allows uniquely identifying a record by a partial key value. * For example, the key could contain multiple fields but could uniquely * identify the record with a single field. The partial comparator could * then compare only the single identifying field. A query ({@link * Cursor#getSearchKey Cursor.getSearchKey}, for example) could then be * performed by passing a partial key that contains only the identifying * field.
* *WARNING: All partial comparators must implement * the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0 * or earlier" in the change log and the {@link PartialComparator} javadoc * for more information.
** Another special type of comparator is a binary equality * comparator, which considers two keys to be equal if and only if they * have the same length and they are equal byte-per-byte. All binary * equality comparators must implement the {@link BinaryEqualityComparator} * interface. The significance of binary equality comparators is that they * make possible certain internal optimizations, like the "blind puts" * optimization, described in * {@link BinaryEqualityComparator} *
* The comparator for an existing database will not be overridden unless
* setOverrideBtreeComparator() is set to true.
*
* @return this
*/
public DatabaseConfig setBtreeComparator(
Comparator Note that there are two ways to set the comparator: by specifying the
* class or by specifying a serializable object. This method is used to
* specify a Comparator class. The comparator class must implement
* java.util.Comparator and must have a public zero-parameter constructor.
* JE will store the class name and instantiate the Comparator by class
* name (using The Comparator.compare() method is passed the byte arrays that are
* stored in the database. If you know how your data is organized in the
* byte array, then you can write a comparison routine that directly
* examines the contents of the arrays. Otherwise, you have to reconstruct
* your original objects, and then perform the comparison. See the Getting Started Guide for examples. If a comparator needs to be initialized before it is used or needs
* access to the environment's ClassLoader property, it may implement the
* {@link DatabaseComparator} interface. WARNING: There are several special considerations that must
* be taken into account when implementing a comparator.
* A special type of comparator is a partial comparator, which
* compares a proper subset (not all bytes) of the key. A partial
* comparator allows uniquely identifying a record by a partial key value.
* For example, the key could contain multiple fields but could uniquely
* identify the record with a single field. The partial comparator could
* then compare only the single identifying field. A query ({@link
* Cursor#getSearchKey Cursor.getSearchKey}, for example) could then be
* performed by passing a partial key that contains only the identifying
* field. WARNING: All partial comparators must implement
* the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0
* or earlier" in the change log and the {@link PartialComparator} javadoc
* for more information.
* Another special type of comparator is a binary equality
* comparator, which considers two keys to be equal if and only if they
* have the same length and they are equal byte-per-byte. All binary
* equality comparators must implement the {@link BinaryEqualityComparator}
* interface. The significance of binary equality comparators is that they
* make possible certain internal optimizations, like the "blind puts"
* optimization, described in
* {@link BinaryEqualityComparator}
*
* The comparator for an existing database will not be overridden unless
* setOverrideBtreeComparator() is set to true.
*
* @return this
*/
public DatabaseConfig setBtreeComparator(
Class extends Comparator Note that there are two ways to set the comparator: by specifying the
* class or by specifying a serializable object. This method is used to
* specify a serializable object. The comparator class must implement
* java.util.Comparator and must be serializable. JE will serialize the
* Comparator and deserialize it when subsequently opening the
* database. The Comparator.compare() method is passed the byte arrays that are
* stored in the database. If you know how your data is organized in the
* byte array, then you can write a comparison routine that directly
* examines the contents of the arrays. Otherwise, you have to reconstruct
* your original objects, and then perform the comparison. See the Getting Started Guide for examples. If a comparator needs to be initialized before it is used or needs
* access to the environment's ClassLoader property, it may implement the
* {@link DatabaseComparator} interface. WARNING: There are several special considerations that must
* be taken into account when implementing a comparator.
* A special type of comparator is a partial comparator, which
* is a comparator that compares a proper subset (not all bytes) of the
* data. A partial comparator allows uniquely identifying a record within
* a duplicate set by a partial data value. For example, the data could
* contain multiple fields but could uniquely identify the record with a
* single field. The partial comparator could then compare only the single
* identifying field. A query ({@link Cursor#getSearchBoth
* Cursor.getSearchBoth}, for example) could then be performed by passing a
* partial data value that contains only the identifying field. When using a partial comparator, it is possible to update the data
* for a duplicate record, as long as only the non-identifying fields in
* the data are changed. See {@link Cursor#putCurrent Cursor.putCurrent}
* for more information. WARNING: All partial comparators must implement
* the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0
* or earlier" in the change log and the {@link PartialComparator} javadoc
* for more information.
* Another special type of comparator is a binary equality
* comparator, which considers two keys to be equal if and only if they
* have the same length and they are equal byte-per-byte. All binary
* equality comparators must implement the {@link BinaryEqualityComparator}
* interface. The significance of binary equality comparators is that they
* make possible certain internal optimizations, like the "blind puts"
* optimization, described in
* {@link BinaryEqualityComparator}
*
* The comparator for an existing database will not be overridden unless
* setOverrideDuplicateComparator() is set to true.
*/
public DatabaseConfig setDuplicateComparator(
Comparator Note that there are two ways to set the comparator: by specifying the
* class or by specifying a serializable object. This method is used to
* specify a Comparator class. The comparator class must implement
* java.util.Comparator and must have a public zero-parameter constructor.
* JE will store the class name and instantiate the Comparator by class
* name (using The Comparator.compare() method is passed the byte arrays that are
* stored in the database. If you know how your data is organized in the
* byte array, then you can write a comparison routine that directly
* examines the contents of the arrays. Otherwise, you have to reconstruct
* your original objects, and then perform the comparison. See the Getting Started Guide for examples. If a comparator needs to be initialized before it is used or needs
* access to the environment's ClassLoader property, it may implement the
* {@link DatabaseComparator} interface. WARNING: There are several special considerations that must
* be taken into account when implementing a comparator.
* A special type of comparator is a partial comparator, which
* is a comparator that compares a proper subset (not all bytes) of the
* data. A partial comparator allows uniquely identifying a record within
* a duplicate set by a partial data value. For example, the data could
* contain multiple fields but could uniquely identify the record with a
* single field. The partial comparator could then compare only the single
* identifying field. A query ({@link Cursor#getSearchBoth
* Cursor.getSearchBoth}, for example) could then be performed by passing a
* partial data value that contains only the identifying field. When using a partial comparator, it is possible to update the data
* for a duplicate record, as long as only the non-identifying fields in
* the data are changed. See {@link Cursor#putCurrent Cursor.putCurrent}
* for more information. WARNING: All partial comparators must implement
* the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0
* or earlier" in the change log and the {@link PartialComparator} javadoc
* for more information.
* Another special type of comparator is a binary equality
* comparator, which considers two keys to be equal if and only if they
* have the same length and they are equal byte-per-byte. All binary
* equality comparators must implement the {@link BinaryEqualityComparator}
* interface. The significance of binary equality comparators is that they
* make possible certain internal optimizations, like the "blind puts"
* optimization, described in
* {@link BinaryEqualityComparator}
*
* The comparator for an existing database will not be overridden unless
* setOverrideDuplicateComparator() is set to true.
*
* @return this
*/
public DatabaseConfig setDuplicateComparator(
Class extends Comparator
* This configuration parameter is only meaningful when configuring a
*
* The type of the trigger specified in the list must match the type of
* database being configured. For example, the trigger object must
* implement the
* Some of the incorrect uses of this parameter are detected during calls
* to {@link Environment#openDatabase Environment.openDatabase} or
* {@link Environment#openSecondaryDatabase
* Environment.openSecondaryDatabase} and will result in an
* Temporary databases operate internally in deferred-write mode to
* provide reduced disk I/O and increased concurrency. But unlike an
* ordinary deferred-write database, the information in a temporary
* database is not durable or persistent.
*
* A temporary database is not flushed to disk when the database is
* closed or when a checkpoint is performed, and the Database.sync method
* may not be called. When all handles for a temporary database are
* closed, the database is automatically removed. If a crash occurs before
* closing a temporary database, the database will be automatically removed
* when the environment is re-opened.
*
* Note that although temporary databases can page to disk if the cache
* is not large enough to hold the databases, they are much more efficient
* if the database remains in memory. See the JE FAQ on the Oracle
* Technology Network site for information on how to estimate the cache
* size needed by a given database.
*
*
* See the {@link Getting
* Started Guide, Database chapter} for a full description of temporary
* databases.
*
* @param temporary if true, the database will be opened as a temporary
* database.
*
* @return this
*/
public DatabaseConfig setTemporary(boolean temporary) {
setTemporaryVoid(temporary);
return this;
}
/**
* @hidden
* The void return setter for use by Bean editors.
*/
public void setTemporaryVoid(boolean temporary) {
this.temporary = temporary;
}
/**
* Returns the temporary database option.
* @return boolean if true, the database is temporary.
*/
public boolean getTemporary() {
return temporary;
}
/**
* Sets the deferred-write option.
*
* Deferred-write databases have reduced disk I/O and improved
* concurrency. Disk I/O is reduced when data records are frequently
* modified or deleted. The information in a deferred-write database is
* not guaranteed to be durable or persistent until {@link Database#close}
* or {@link Database#sync} is called, or a checkpoint is performed. Since
* the usual write ahead logging system is relaxed in order to improve
* performance, if the environment crashes before a {@link Database#sync}
* or {@link Database#close}, none, all, or a unpredictable set of the
* operations previously done may be persistent.
*
* After a deferred-write database is closed it may be re-opened as an
* ordinary transactional or non-transactional database. For example, this
* can be used to initially load a large data set in deferred-write mode
* and then switch to transactional mode for subsequent operations.
*
* Note that although deferred-write databases can page to disk if the
* cache is not large enough to hold the databases, they are much more
* efficient if the database remains in memory. See the JE FAQ on the
* Oracle Technology Network site for information on how to estimate the
* cache size needed by a given database.
*
*
* See the {@link Getting
* Started Guide, Database chapter} for a full description
* of deferred-write databases.
*
*
* @param deferredWrite if true, the database will be opened as a
* deferred-write database.
*
* @return this
*/
public DatabaseConfig setDeferredWrite(boolean deferredWrite) {
setDeferredWriteVoid(deferredWrite);
return this;
}
/**
* @hidden
* The void return setter for use by Bean editors.
*/
public void setDeferredWriteVoid(boolean deferredWrite) {
this.deferredWrite = deferredWrite;
}
/**
* Returns the deferred-write option.
*
* @return boolean if true, deferred-write is enabled.
*/
public boolean getDeferredWrite() {
return deferredWrite;
}
/**
* Used to set the comparator when filling in a configuration from an
* existing database.
*/
void setBtreeComparatorInternal(Comparator
* In a non-replicated Environment, this property is ignored. All
* databases are non-replicated in a non-replicated Environment.
*
* @see
* Non-replicated
* Databases in a Replicated Environment
*/
public DatabaseConfig setReplicated(boolean replicated) {
setReplicatedVoid(replicated);
return this;
}
/**
* @hidden
* The void return setter for use by Bean editors.
*/
public void setReplicatedVoid(boolean replicated) {
this.replicated = replicated;
}
/**
* Returns the replicated property for the database.
*
* This method returns true by default. However, in a non-replicated
* Environment, this property is ignored. All databases are non-replicated
* in a non-replicated Environment.
*
* @see #setReplicated
*/
public boolean getReplicated() {
return replicated;
}
/**
* @hidden
* For internal use only.
*
* Configures a SecondaryAssociation that is used to define
* primary-secondary associations for a group of primary and secondary
* databases. The same SecondaryAssociation instance must be configured on
* the primary and secondary databases.
*
* @see SecondaryAssociation
*/
public DatabaseConfig
setSecondaryAssociation(SecondaryAssociation association) {
setSecondaryAssociationVoid(association);
return this;
}
/**
* @hidden
* The void return setter for use by Bean editors.
*/
public void setSecondaryAssociationVoid(SecondaryAssociation association) {
secAssociation = association;
}
/**
* @hidden
* For internal use only.
*
* Returns the configured SecondaryAssociation.
*
* @see #setSecondaryAssociation
* @see SecondaryAssociation
*/
public SecondaryAssociation getSecondaryAssociation() {
return secAssociation;
}
/**
* Returns a copy of this configuration object.
*
* @deprecated As of JE 4.0.13, replaced by {@link
* DatabaseConfig#clone()}.Class.forName
and newInstance
)
* when subsequently opening the database. Because the Comparator is
* instantiated using its default constructor, it should not be dependent
* on other constructor parameters.
*
*
*
*
*
* Class.forName
and newInstance
)
* when subsequently opening the database. Because the Comparator is
* instantiated using its default constructor, it should not be dependent
* on other constructor parameters.
*
*
* Primary
database.
* ReplicatedDatabaseTrigger
interface if it's
* used to configure a replicated database.
* IllegalArgumentException
.
*
* @param triggers the list of database triggers to be associated with the
* environment.
*
* @throws IllegalArgumentException If the triggers in the list do not have
* unique names, have conflicting types (e.g. only a subset implement
* {@link ReplicatedDatabaseTrigger ReplicatedDatabaseTrigger}), or do not
* implement {@link ReplicatedDatabaseTrigger ReplicatedDatabaseTrigger}
* for a replicated database.
*
* @return this
*/
public DatabaseConfig setTriggers(List