1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2002,2008 Oracle.  All rights reserved.
5 *
6 * $Id: Environment.java,v 12.26 2008/04/02 13:43:38 bschmeck Exp $
7 */
8
9package com.sleepycat.db;
10
11import com.sleepycat.db.internal.DbConstants;
12import com.sleepycat.db.internal.DbEnv;
13
14/**
15A database environment.  Environments include support for some or
16all of caching, locking, logging and transactions.
17<p>
18To open an existing environment with default attributes the application
19may use a default environment configuration object or null:
20<p>
21<blockquote><pre>
22    // Open an environment handle with default attributes.
23    Environment env = new Environment(home, new EnvironmentConfig());
24</pre></blockquote>
25<p>
26or
27<p>
28<blockquote><pre>
29    Environment env = new Environment(home, null);
30</pre></blockquote>
31<p>
32Note that many Environment objects may access a single environment.
33<p>
34To create an environment or customize attributes, the application should
35customize the configuration class. For example:
36<p>
37<blockquote><pre>
38    EnvironmentConfig envConfig = new EnvironmentConfig();
39    envConfig.setTransactional(true);
40    envConfig.setAllowCreate(true);
41    envConfig.setCacheSize(1000000);
42    <p>
43    Environment newlyCreatedEnv = new Environment(home, envConfig);
44</pre></blockquote>
45<p>
46Environment handles are free-threaded unless {@link com.sleepycat.db.EnvironmentConfig#setThreaded EnvironmentConfig.setThreaded} is called to disable this before the environment is opened.
47<p>
48An <em>environment handle</em> is an Environment instance.  More than
49one Environment instance may be created for the same physical directory,
50which is the same as saying that more than one Environment handle may
51be open at one time for a given environment.
52<p>
53The Environment handle should not be closed while any other handle
54remains open that is using it as a reference (for example,
55{@link com.sleepycat.db.Database Database} or {@link com.sleepycat.db.Transaction Transaction}.  Once {@link com.sleepycat.db.Environment#close Environment.close}
56is called, this object may not be accessed again, regardless of
57whether or not it throws an exception.
58*/
59public class Environment {
60    private DbEnv dbenv;
61    private int autoCommitFlag;
62
63    /* package */
64    Environment(final DbEnv dbenv)
65        throws DatabaseException {
66
67        this.dbenv = dbenv;
68        dbenv.wrapper = this;
69    }
70
71    /**
72    Create a database environment handle.
73    <p>
74    @param home
75    The database environment's home directory.
76    The environment variable <code>DB_HOME</code> may be used as
77    the path of the database home.
78    For more information on <code>envHome</code> and filename
79    resolution in general, see
80    <a href="{@docRoot}/../ref/env/naming.html" target="_top">File Naming</a>.
81    <p>
82    @param config The database environment attributes.  If null, default attributes are used.
83    <p>
84    <p>
85    @throws IllegalArgumentException if an invalid parameter was specified.
86    <p>
87    <p>
88    @throws DatabaseException if a failure occurs.
89    */
90    public Environment(final java.io.File home, EnvironmentConfig config)
91        throws DatabaseException, java.io.FileNotFoundException {
92
93        this(EnvironmentConfig.checkNull(config).openEnvironment(home));
94        this.autoCommitFlag =
95            ((dbenv.get_open_flags() & DbConstants.DB_INIT_TXN) == 0) ? 0 :
96                DbConstants.DB_AUTO_COMMIT;
97    }
98
99    /**
100    Close the database environment, freeing any allocated resources and
101    closing any underlying subsystems.
102    <p>
103    The {@link com.sleepycat.db.Environment Environment} handle should not be closed while any other
104    handle that refers to it is not yet closed; for example, database
105    environment handles must not be closed while database handles remain
106    open, or transactions in the environment have not yet been committed
107    or aborted.  Specifically, this includes {@link com.sleepycat.db.Database Database},
108    {@link com.sleepycat.db.Cursor Cursor}, {@link com.sleepycat.db.Transaction Transaction}, and {@link com.sleepycat.db.LogCursor LogCursor}
109    handles.
110    <p>
111    Where the environment was initialized with a locking subsystem,
112    closing the environment does not release any locks still held by the
113    closing process, providing functionality for long-lived locks.
114    <p>
115    Where the environment was initialized with a transaction subsystem,
116    closing the environment aborts any unresolved transactions.
117    Applications should not depend on this behavior for transactions
118    involving databases; all such transactions should be explicitly
119    resolved.  The problem with depending on this semantic is that
120    aborting an unresolved transaction involving database operations
121    requires a database handle.  Because the database handles should
122    have been closed before closing the environment, it will not be
123    possible to abort the transaction, and recovery will have to be run
124    on the database environment before further operations are done.
125    <p>
126    Where log cursors were created, closing the environment does not
127    imply closing those cursors.
128    <p>
129    In multithreaded applications, only a single thread may call this
130    method.
131    <p>
132    After this method has been called, regardless of its return, the
133    {@link com.sleepycat.db.Environment Environment} handle may not be accessed again.
134    <p>
135    <p>
136@throws DatabaseException if a failure occurs.
137    */
138    public void close()
139        throws DatabaseException {
140
141        dbenv.close(0);
142    }
143
144    /* package */
145    DbEnv unwrap() {
146        return dbenv;
147    }
148
149    /**
150    Destroy a database environment.
151    <p>
152    If the environment is not in use, the environment regions, including
153    any backing files, are removed.  Any log or database files and the
154    environment directory itself are not removed.
155    <p>
156    If there are processes currently using the database environment,
157    this method will fail without further action (unless the force
158    argument is true, in which case the environment will be removed,
159    regardless of any processes still using it).
160    <p>
161    The result of attempting to forcibly destroy the environment when
162    it is in use is unspecified.  Processes using an environment often
163    maintain open file descriptors for shared regions within it.  On
164    UNIX systems, the environment removal will usually succeed, and
165    processes that have already joined the region will continue to run
166    in that region without change.  However, processes attempting to
167    join the environment will either fail or create new regions.  On
168    other systems in which the unlink system call will fail if any
169    process has an open file descriptor for the file (for example
170    Windows/NT), the region removal will fail.
171    <p>
172    Calling this method should not be necessary for most applications
173    because the environment is cleaned up as part of normal
174    database recovery procedures. However, applications may want to call
175    this method as part of application shut down to free up system
176    resources.  For example, if system shared memory was used to back
177    the database environment, it may be useful to call this method in
178    order to release system shared memory segments that have been
179    allocated.  Or, on architectures in which mutexes require allocation
180    of underlying system resources, it may be useful to call
181    this method in order to release those resources.  Alternatively, if
182    recovery is not required because no database state is maintained
183    across failures, and no system resources need to be released, it is
184    possible to clean up an environment by simply removing all the
185    Berkeley DB files in the database environment's directories.
186    <p>
187    In multithreaded applications, only a single thread may call this
188    method.
189    <p>
190    After this method has been called, regardless of its return, the
191    {@link com.sleepycat.db.Environment Environment} handle may not be
192    accessed again.
193    <p>
194    @param home
195    The database environment to be removed.
196    On Windows platforms, this argument will be interpreted as a UTF-8
197    string, which is equivalent to ASCII for Latin characters.
198    <p>
199    @param force
200    The environment is removed, regardless of any processes that may
201    still using it, and no locks are acquired during this process.
202    (Generally, the force argument is specified only when applications
203    were unable to shut down cleanly, and there is a risk that an
204    application may have died holding a Berkeley DB mutex or lock.
205    <p>
206    <p>
207    @throws DatabaseException if a failure occurs.
208    */
209    public static void remove(final java.io.File home,
210                              final boolean force,
211                              EnvironmentConfig config)
212        throws DatabaseException, java.io.FileNotFoundException {
213
214        config = EnvironmentConfig.checkNull(config);
215        int flags = force ? DbConstants.DB_FORCE : 0;
216        flags |= config.getUseEnvironment() ?
217            DbConstants.DB_USE_ENVIRON : 0;
218        flags |= config.getUseEnvironmentRoot() ?
219            DbConstants.DB_USE_ENVIRON_ROOT : 0;
220        final DbEnv dbenv = config.createEnvironment();
221        dbenv.remove((home == null) ? null : home.toString(), flags);
222    }
223
224    /**
225    Change the settings in an existing environment handle.
226    <p>
227    @param config The database environment attributes.  If null, default attributes are used.
228    <p>
229    <p>
230@throws IllegalArgumentException if an invalid parameter was specified.
231<p>
232@throws DatabaseException if a failure occurs.
233    */
234    public void setConfig(final EnvironmentConfig config)
235        throws DatabaseException {
236
237        config.configureEnvironment(dbenv, new EnvironmentConfig(dbenv));
238    }
239
240    /**
241    Return this object's configuration.
242    <p>
243    @return
244    This object's configuration.
245    <p>
246    <p>
247@throws DatabaseException if a failure occurs.
248    */
249    public EnvironmentConfig getConfig()
250        throws DatabaseException {
251
252        return new EnvironmentConfig(dbenv);
253    }
254
255    /* Manage databases. */
256    /**
257    Open a database.
258<p>
259The database is represented by the file and database parameters.
260<p>
261The currently supported database file formats (or <em>access
262methods</em>) are Btree, Hash, Queue, and Recno.  The Btree format is a
263representation of a sorted, balanced tree structure.  The Hash format
264is an extensible, dynamic hashing scheme.  The Queue format supports
265fast access to fixed-length records accessed sequentially or by logical
266record number.  The Recno format supports fixed- or variable-length
267records, accessed sequentially or by logical record number, and
268optionally backed by a flat text file.
269<p>
270Storage and retrieval are based on key/data pairs; see {@link com.sleepycat.db.DatabaseEntry DatabaseEntry}
271for more information.
272<p>
273Opening a database is a relatively expensive operation, and maintaining
274a set of open databases will normally be preferable to repeatedly
275opening and closing the database for each new query.
276<p>
277In-memory databases never intended to be preserved on disk may be
278created by setting both the fileName and databaseName parameters to
279null.  Note that in-memory databases can only ever be shared by sharing
280the single database handle that created them, in circumstances where
281doing so is safe.  The environment variable <code>TMPDIR</code> may
282be used as a directory in which to create temporary backing files.
283<p>
284@param txn
285For a transactional database, an explicit transaction may be specified, or null
286may be specified to use auto-commit.  For a non-transactional database, null
287must be specified.
288Note that transactionally protected operations on a Database handle
289require that the Database handle itself be transactionally protected
290during its open, either with a non-null transaction handle, or by calling
291{@link com.sleepycat.db.DatabaseConfig#setTransactional DatabaseConfig.setTransactional} on the configuration object.
292<p>
293@param fileName
294The name of an underlying file that will be used to back the database.
295On Windows platforms, this argument will be interpreted as a UTF-8
296string, which is equivalent to ASCII for Latin characters.
297<p>
298@param databaseName
299An optional parameter that allows applications to have multiple
300databases in a single file.  Although no databaseName parameter needs
301to be specified, it is an error to attempt to open a second database in
302a physical file that was not initially created using a databaseName
303parameter.  Further, the databaseName parameter is not supported by the
304Queue format.
305<p>
306@param config The database open attributes.  If null, default attributes are used.
307    */
308    public Database openDatabase(final Transaction txn,
309                                 final String fileName,
310                                 final String databaseName,
311                                 DatabaseConfig config)
312        throws DatabaseException, java.io.FileNotFoundException {
313
314        return new Database(
315            DatabaseConfig.checkNull(config).openDatabase(dbenv,
316                (txn == null) ? null : txn.txn,
317                fileName, databaseName));
318    }
319
320    /**
321    Open a database.
322<p>
323The database is represented by the file and database parameters.
324<p>
325The currently supported database file formats (or <em>access
326methods</em>) are Btree, Hash, Queue, and Recno.  The Btree format is a
327representation of a sorted, balanced tree structure.  The Hash format
328is an extensible, dynamic hashing scheme.  The Queue format supports
329fast access to fixed-length records accessed sequentially or by logical
330record number.  The Recno format supports fixed- or variable-length
331records, accessed sequentially or by logical record number, and
332optionally backed by a flat text file.
333<p>
334Storage and retrieval are based on key/data pairs; see {@link com.sleepycat.db.DatabaseEntry DatabaseEntry}
335for more information.
336<p>
337Opening a database is a relatively expensive operation, and maintaining
338a set of open databases will normally be preferable to repeatedly
339opening and closing the database for each new query.
340<p>
341In-memory databases never intended to be preserved on disk may be
342created by setting both the fileName and databaseName parameters to
343null.  Note that in-memory databases can only ever be shared by sharing
344the single database handle that created them, in circumstances where
345doing so is safe.  The environment variable <code>TMPDIR</code> may
346be used as a directory in which to create temporary backing files.
347<p>
348@param txn
349For a transactional database, an explicit transaction may be specified, or null
350may be specified to use auto-commit.  For a non-transactional database, null
351must be specified.
352Note that transactionally protected operations on a Database handle
353require that the Database handle itself be transactionally protected
354during its open, either with a non-null transaction handle, or by calling
355{@link com.sleepycat.db.DatabaseConfig#setTransactional DatabaseConfig.setTransactional} on the configuration object.
356<p>
357@param fileName
358The name of an underlying file that will be used to back the database.
359On Windows platforms, this argument will be interpreted as a UTF-8
360string, which is equivalent to ASCII for Latin characters.
361<p>
362@param databaseName
363An optional parameter that allows applications to have multiple
364databases in a single file.  Although no databaseName parameter needs
365to be specified, it is an error to attempt to open a second database in
366a physical file that was not initially created using a databaseName
367parameter.  Further, the databaseName parameter is not supported by the
368Queue format.
369<p>
370@param primaryDatabase
371a database handle for the primary database that is to be indexed.
372<p>
373@param config The secondary database open attributes.  If null, default attributes are used.
374    */
375    public SecondaryDatabase openSecondaryDatabase(
376            final Transaction txn,
377            final String fileName,
378            final String databaseName,
379            final Database primaryDatabase,
380            SecondaryConfig config)
381        throws DatabaseException, java.io.FileNotFoundException {
382
383        return new SecondaryDatabase(
384            SecondaryConfig.checkNull(config).openSecondaryDatabase(
385                dbenv, (txn == null) ? null : txn.txn,
386                fileName, databaseName, primaryDatabase.db),
387            primaryDatabase);
388    }
389
390    /**
391    <p>
392Remove a database.
393<p>
394If no database is specified, the underlying file specified is removed.
395<p>
396Applications should never remove databases with open {@link com.sleepycat.db.Database Database}
397handles, or in the case of removing a file, when any database in the
398file has an open handle.  For example, some architectures do not permit
399the removal of files with open system handles.  On these architectures,
400attempts to remove databases currently in use by any thread of control
401in the system may fail.
402<p>
403The
404environment variable DB_HOME may be used as the path of the database
405environment home.
406<p>
407This method is affected by any database directory specified with
408{@link com.sleepycat.db.EnvironmentConfig#addDataDir EnvironmentConfig.addDataDir}, or by setting the "set_data_dir"
409string in the database environment's DB_CONFIG file.
410<p>
411The {@link com.sleepycat.db.Database Database} handle may not be accessed
412again after this method is called, regardless of this method's success
413or failure.
414<p>
415@param txn
416For a transactional database, an explicit transaction may be specified, or null
417may be specified to use auto-commit.  For a non-transactional database, null
418must be specified.
419<p>
420@param fileName
421The physical file which contains the database to be removed.
422On Windows platforms, this argument will be interpreted as a UTF-8
423string, which is equivalent to ASCII for Latin characters.
424<p>
425@param databaseName
426The database to be removed.
427<p>
428<p>
429@throws DeadlockException if the operation was selected to resolve a
430deadlock.
431<p>
432@throws DatabaseException if a failure occurs.
433    */
434    public void removeDatabase(final Transaction txn,
435                               final String fileName,
436                               final String databaseName)
437        throws DatabaseException, java.io.FileNotFoundException {
438
439        dbenv.dbremove((txn == null) ? null : txn.txn,
440            fileName, databaseName,
441            (txn == null) ? autoCommitFlag : 0);
442    }
443
444    /**
445    <p>
446Rename a database.
447<p>
448If no database name is specified, the underlying file specified is
449renamed, incidentally renaming all of the databases it contains.
450<p>
451Applications should never rename databases that are currently in use.
452If an underlying file is being renamed and logging is currently enabled
453in the database environment, no database in the file may be open when
454this method is called.  In particular, some architectures do not permit
455renaming files with open handles.  On these architectures, attempts to
456rename databases that are currently in use by any thread of control in
457the system may fail.
458<p>
459The
460environment variable DB_HOME may be used as the path of the database
461environment home.
462<p>
463This method is affected by any database directory specified with
464{@link com.sleepycat.db.EnvironmentConfig#addDataDir EnvironmentConfig.addDataDir}, or by setting the "set_data_dir"
465string in the database environment's DB_CONFIG file.
466<p>
467The {@link com.sleepycat.db.Database Database} handle may not be accessed
468again after this method is called, regardless of this method's success
469or failure.
470<p>
471@param txn
472For a transactional database, an explicit transaction may be specified, or null
473may be specified to use auto-commit.  For a non-transactional database, null
474must be specified.
475<p>
476@param fileName
477The physical file which contains the database to be renamed.
478On Windows platforms, this argument will be interpreted as a UTF-8
479string, which is equivalent to ASCII for Latin characters.
480<p>
481@param databaseName
482The database to be renamed.
483<p>
484@param newName
485The new name of the database or file.
486<p>
487<p>
488@throws DeadlockException if the operation was selected to resolve a
489deadlock.
490<p>
491@throws DatabaseException if a failure occurs.
492    */
493    public void renameDatabase(final Transaction txn,
494                               final String fileName,
495                               final String databaseName,
496                               final String newName)
497        throws DatabaseException, java.io.FileNotFoundException {
498
499        dbenv.dbrename((txn == null) ? null : txn.txn,
500            fileName, databaseName, newName,
501            (txn == null) ? autoCommitFlag : 0);
502    }
503
504    public java.io.File getHome()
505        throws DatabaseException {
506
507        String home = dbenv.get_home();
508        return (home == null) ? null : new java.io.File(home);
509    }
510
511    /* Cache management. */
512    /**
513    Ensure that a specified percent of the pages in the shared memory
514    pool are clean, by writing dirty pages to their backing files.
515    <p>
516    The purpose of this method is to enable a memory pool manager to ensure
517    that a page is always available for reading in new information
518    without having to wait for a write.
519    <p>
520    @param percent
521    The percent of the pages in the cache that should be clean.
522    <p>
523    @return
524    The number of pages that were written to reach the specified
525    percentage.
526    <p>
527    <p>
528@throws DatabaseException if a failure occurs.
529    */
530    public int trickleCacheWrite(int percent)
531        throws DatabaseException {
532
533        return dbenv.memp_trickle(percent);
534    }
535
536    /* Locking */
537    /**
538    Run one iteration of the deadlock detector.
539    <p>
540    The deadlock detector traverses the lock table and marks one of the
541    participating lock requesters for rejection in each deadlock it finds.
542    <p>
543    @param mode
544    Which lock request(s) to reject.
545    <p>
546    @return
547    The number of lock requests that were rejected.
548    <p>
549    <p>
550@throws DatabaseException if a failure occurs.
551    */
552    public int detectDeadlocks(LockDetectMode mode)
553        throws DatabaseException {
554
555        return dbenv.lock_detect(0, mode.getFlag());
556    }
557
558    /**
559    Acquire a lock from the lock table.
560    <p>
561    @param locker
562    An unsigned 32-bit integer quantity representing the entity
563    requesting the lock.
564    <p>
565    @param mode
566    The lock mode.
567    <p>
568    @param noWait
569    If a lock cannot be granted because the requested lock conflicts
570    with an existing lock, throw a {@link com.sleepycat.db.LockNotGrantedException LockNotGrantedException}
571    immediately instead of waiting for the lock to become available.
572    <p>
573    @param object
574    An untyped byte string that specifies the object to be locked.
575    Applications using the locking subsystem directly while also doing
576    locking via the Berkeley DB access methods must take care not to
577    inadvertently lock objects that happen to be equal to the unique
578    file IDs used to lock files.
579    <p>
580    <p>
581@throws DatabaseException if a failure occurs.
582    */
583    public Lock getLock(int locker,
584                        boolean noWait,
585                        DatabaseEntry object,
586                        LockRequestMode mode)
587        throws DatabaseException {
588
589        return Lock.wrap(
590            dbenv.lock_get(locker, noWait ? DbConstants.DB_LOCK_NOWAIT : 0,
591                object, mode.getFlag()));
592    }
593
594    /**
595    Release a lock.
596    <p>
597    @param lock
598    The lock to be released.
599    <p>
600    <p>
601@throws DatabaseException if a failure occurs.
602    */
603    public void putLock(Lock lock)
604        throws DatabaseException {
605
606        dbenv.lock_put(lock.unwrap());
607    }
608
609    /**
610    Allocate a locker ID.
611    <p>
612    The locker ID is guaranteed to be unique for the database environment.
613    <p>
614    Call {@link com.sleepycat.db.Environment#freeLockerID Environment.freeLockerID} to return the locker ID to
615    the environment when it is no longer needed.
616    <p>
617    @return
618    A locker ID.
619    */
620    public int createLockerID()
621        throws DatabaseException {
622
623        return dbenv.lock_id();
624    }
625
626    /**
627    Free a locker ID.
628    <p>
629    @param id
630    The locker id to be freed.
631    <p>
632    <p>
633@throws DatabaseException if a failure occurs.
634    */
635    public void freeLockerID(int id)
636        throws DatabaseException {
637
638        dbenv.lock_id_free(id);
639    }
640
641    /**
642    Atomically obtain and release one or more locks from the lock table.
643    This method is intended to support acquisition or trading of
644    multiple locks under one lock table semaphore, as is needed for lock
645    coupling or in multigranularity locking for lock escalation.
646    <p>
647    If any of the requested locks cannot be acquired, or any of the locks to
648    be released cannot be released, the operations before the failing
649    operation are guaranteed to have completed successfully, and
650    the method throws an exception.
651    <p>
652    @param noWait
653    If a lock cannot be granted because the requested lock conflicts
654    with an existing lock, throw a {@link com.sleepycat.db.LockNotGrantedException LockNotGrantedException}
655    immediately instead of waiting for the lock to become available.
656    The index of the request that was not granted will be returned by
657    {@link com.sleepycat.db.LockNotGrantedException#getIndex LockNotGrantedException.getIndex}.
658    <p>
659    @param locker
660    An unsigned 32-bit integer quantity representing the entity
661    requesting the lock.
662    <p>
663    @param list
664    An array of {@link com.sleepycat.db.LockRequest LockRequest} objects, listing the requested lock
665    operations.
666    <p>
667    <p>
668@throws DatabaseException if a failure occurs.
669    */
670    public void lockVector(int locker, boolean noWait, LockRequest[] list)
671        throws DatabaseException {
672
673        dbenv.lock_vec(locker, noWait ? DbConstants.DB_LOCK_NOWAIT : 0,
674            list, 0, list.length);
675    }
676
677    /* Logging */
678    /**
679    Return a log cursor.
680    <p>
681    @return
682    A log cursor.
683    <p>
684    <p>
685@throws DatabaseException if a failure occurs.
686    */
687    public LogCursor openLogCursor()
688        throws DatabaseException {
689
690        return LogCursor.wrap(dbenv.log_cursor(0));
691    }
692
693    /**
694    Return the name of the log file that contains the log record
695    specified by a LogSequenceNumber object.
696    <p>
697    This mapping of LogSequenceNumber objects to files is needed for
698    database administration.  For example, a transaction manager
699    typically records the earliest LogSequenceNumber object needed for
700    restart, and the database administrator may want to archive log
701    files to tape when they contain only log records before the earliest
702    one needed for restart.
703    <p>
704    @param lsn
705    The LogSequenceNumber object for which a filename is wanted.
706    <p>
707    @return
708    The name of the log file that contains the log record specified by a
709    LogSequenceNumber object.
710    <p>
711    <p>
712@throws IllegalArgumentException if an invalid parameter was specified.
713<p>
714@throws DatabaseException if a failure occurs.
715    */
716    public String getLogFileName(LogSequenceNumber lsn)
717        throws DatabaseException {
718
719        return dbenv.log_file(lsn);
720    }
721
722    /* Replication support */
723    /**
724    Configure the database environment as a client or master in a group
725    of replicated database environments.  Replication master
726    environments are the only database environments where replicated
727    databases may be modified.  Replication client environments are
728    read-only as long as they are clients.  Replication client
729    environments may be upgraded to be replication master environments
730    in the case that the current master fails or there is no master
731    present.
732    <p>
733    The enclosing database environment must already have been configured
734    to send replication messages by calling {@link com.sleepycat.db.EnvironmentConfig#setReplicationTransport EnvironmentConfig.setReplicationTransport}.
735    <p>
736    @param cdata
737    An opaque data item that is sent over the communication infrastructure
738    when the client or master comes online.  If no such information is
739    useful, cdata should be null.
740    <p>
741    @param master
742    Configure the environment as a replication master.  If false, the
743    environment will be configured as as a replication client.
744    <p>
745    <p>
746@throws DatabaseException if a failure occurs.
747    */
748    public void startReplication(DatabaseEntry cdata, boolean master)
749        throws DatabaseException {
750
751        dbenv.rep_start(cdata,
752            master ? DbConstants.DB_REP_MASTER : DbConstants.DB_REP_CLIENT);
753    }
754
755    /**
756    Hold an election for the master of a replication group.
757    <p>
758    If the election is successful, the new master's ID may be the ID of the
759    previous master, or the ID of the current environment.  The application
760    is responsible for adjusting its usage of the other environments in the
761    replication group, including directing all database updates to the newly
762    selected master, in accordance with the results of this election.
763    <p>
764    The thread of control that calls this method must not be the thread
765    of control that processes incoming messages; processing the incoming
766    messages is necessary to successfully complete an election.
767    <p>
768    @param nsites
769    The number of environments that the application believes are in the
770    replication group.  This number is used by Berkeley DB to avoid
771    having two masters active simultaneously, even in the case of a
772    network partition.  During an election, a new master cannot be
773    elected unless more than half of nsites agree on the new master.
774    Thus, in the face of a network partition, the side of the partition
775    with more than half the environments will elect a new master and
776    continue, while the environments communicating with fewer than half
777    the other environments will fail to find a new master.
778    <p>
779    @param nvotes
780    The number of votes required by the application to successfully
781    elect a new master.  It must be a positive integer, no greater than
782    nsites, or 0 if the election should use a simple majority of the
783    nsites value as the requirement.  A warning is given if half or
784    fewer votes are required to win an election as that can potentially
785    lead to multiple masters in the face of a network partition.
786    <p>
787    <p>
788@throws DatabaseException if a failure occurs.
789    */
790    public void electReplicationMaster(int nsites, int nvotes)
791        throws DatabaseException {
792        dbenv.rep_elect(nsites, nvotes, 0 /* unused flags */);
793    }
794
795    /**
796    Internal method: re-push the last log record to all clients, in case they've
797    lost messages and don't know it.
798    <p>
799    This method may not be called before the database environment is opened.
800    <p>
801    <p>
802@throws DatabaseException if a failure occurs.
803    **/
804    public void flushReplication()
805        throws DatabaseException {
806
807        dbenv.rep_flush();
808    }
809
810    /**
811    Process an incoming replication message sent by a member of the
812    replication group to the local database environment.
813    <p>
814    For implementation reasons, all incoming replication messages must
815    be processed using the same {@link com.sleepycat.db.Environment Environment} handle.  It is not
816    required that a single thread of control process all messages, only
817    that all threads of control processing messages use the same handle.
818    <p>
819    @param control
820    A copy of the control parameter specified by Berkeley DB on the
821    sending environment.
822    <p>
823    @param envid
824    The local identifier that corresponds to the environment that sent
825    the message to be processed.
826    <p>
827    @param rec
828    A copy of the rec parameter specified by Berkeley DB on the sending
829    environment.
830    <p>
831    @return
832    A {@link com.sleepycat.db.ReplicationStatus ReplicationStatus} object.
833    */
834    public ReplicationStatus processReplicationMessage(DatabaseEntry control,
835                                                       DatabaseEntry rec,
836                                                       int envid)
837        throws DatabaseException {
838        // Create a new entry so that rec isn't overwritten
839        final DatabaseEntry cdata =
840            new DatabaseEntry(rec.getData(), rec.getOffset(), rec.getSize());
841        final LogSequenceNumber lsn = new LogSequenceNumber();
842        final int ret =
843            dbenv.rep_process_message(control, cdata, envid, lsn);
844        return ReplicationStatus.getStatus(ret, cdata, envid, lsn);
845    }
846
847    /**
848    Configure the replication subsystem.
849    <p>
850    The database environment's replication subsystem may also be set using the environment's
851DB_CONFIG file.  The syntax of the entry in that file is a single line
852with the string "rep_set_config", one or more whitespace characters, and     the method configuration parameter as a string; for example,
853    "rep_set_config REP_CONF_NOWAIT".
854Because the DB_CONFIG file is read when the database environment is
855opened, it will silently overrule configuration done before that time.
856    <p>
857    This method configures a database environment, including all threads
858of control accessing the database environment, not only the operations
859performed using a specified {@link com.sleepycat.db.Environment Environment} handle.
860    <p>
861    This method may be called at any time during the life of the application.
862    <p>
863    @param config
864    A replication feature to be configured.
865    @param onoff
866    If true, the feature is enabled, otherwise it is disabled.
867    **/
868    public void setReplicationConfig(ReplicationConfig config, boolean onoff)
869        throws DatabaseException {
870
871        dbenv.rep_set_config(config.getFlag(), onoff);
872    }
873
874    /**
875    Get the configuration of the replication subsystem.
876    This method may be called at any time during the life of the application.
877    @return
878    Whether the specified feature is enabled or disabled.
879    **/
880    public boolean getReplicationConfig(ReplicationConfig config)
881        throws DatabaseException {
882
883        return dbenv.rep_get_config(config.getFlag());
884    }
885
886    /**
887    Set the network timeout applied to the specified timeout type.
888    This method may be called at any time during the life of the application.
889    @param type
890    The type of timeout to retrieve.
891    <p>
892    @param replicationTimeout
893    The time in milliseconds of the desired timeout.
894    **/
895    public void setReplicationTimeout(
896        final ReplicationTimeoutType type, final int replicationTimeout)
897        throws DatabaseException {
898
899        dbenv.rep_set_timeout(type.getId(), replicationTimeout);
900    }
901
902    /**
903    Get the network timeout applied to the specified timeout type.
904    @param type
905    The type of timeout to retrieve.
906    <p>
907    @return
908    The network timeout applied to the specified timout type.
909    <p>
910    <p>
911@throws DatabaseException if a failure occurs.
912    **/
913    public int getReplicationTimeout(final ReplicationTimeoutType type)
914        throws DatabaseException {
915
916        return dbenv.rep_get_timeout(type.getId());
917    }
918
919    /**
920    Forces synchronization to begin for this client.  This method is the other
921    half of setting {@link ReplicationConfig#DELAYCLIENT} with
922    {@link #setReplicationConfig}.
923    <p>
924    When a new master is elected and the application has configured delayed
925    synchronization, the application must choose when to perform
926    synchronization by using this method.  Otherwise the client will remain
927    unsynchronized and will ignore all new incoming log messages.
928    <p>
929    This method may not be called before the database environment is opened.
930    <p>
931    <p>
932@throws DatabaseException if a failure occurs.
933    **/
934    public void syncReplication() throws DatabaseException {
935        dbenv.rep_sync(0);
936    }
937
938    /* Replication Manager interface */
939    /**
940    Starts the replication manager.
941    <p>
942    The replication manager is implemented inside the Berkeley DB library,
943    it is designed to manage a replication group. This includes network
944    transport, all replication message processing and acknowledgment, and
945    group elections.
946    <p>
947    For more information on building replication manager applications,
948    please see the "Replication Manager Getting Started Guide" included in
949    the Berkeley DB documentation.
950    <p>
951    This method may not be called before the database environment is opened.
952    @param nthreads
953    Specify the number of threads of control created and dedicated to
954    processing replication messages. In addition to these message processing
955    threads, the replication manager creates and manages a few of its own
956    threads of control.
957    <p>
958    @param policy
959    The policy defines the startup characteristics of a replication group.
960    See {@link com.sleepycat.db.ReplicationManagerStartPolicy ReplicationManagerStartPolicy} for more information.
961    **/
962    public void replicationManagerStart(
963        int nthreads, ReplicationManagerStartPolicy policy)
964        throws DatabaseException {
965
966        dbenv.repmgr_start(nthreads, policy.getId());
967    }
968
969    /**
970    Return an array of all sites known to the replication manager.
971    */
972    public ReplicationManagerSiteInfo[] getReplicationManagerSiteList()
973        throws DatabaseException {
974
975        return dbenv.repmgr_site_list();
976    }
977
978    /* Statistics */
979    public CacheStats getCacheStats(StatsConfig config)
980        throws DatabaseException {
981
982        return dbenv.memp_stat(StatsConfig.checkNull(config).getFlags());
983    }
984
985    public CacheFileStats[] getCacheFileStats(StatsConfig config)
986        throws DatabaseException {
987
988        return dbenv.memp_fstat(StatsConfig.checkNull(config).getFlags());
989    }
990
991    /**
992    Return the database environment's logging statistics.
993    <p>
994    @param config The statistics attributes.  If null, default attributes are used.
995    <p>
996    @return
997    The database environment's logging statistics.
998    <p>
999    <p>
1000@throws DatabaseException if a failure occurs.
1001    */
1002    public LogStats getLogStats(StatsConfig config)
1003        throws DatabaseException {
1004
1005        return dbenv.log_stat(StatsConfig.checkNull(config).getFlags());
1006    }
1007
1008    /**
1009    Return the database environment's replication statistics.
1010    <p>
1011    @param config The statistics attributes.  If null, default attributes are used.
1012    <p>
1013    @return
1014    The database environment's replication statistics.
1015    <p>
1016    <p>
1017@throws DatabaseException if a failure occurs.
1018    */
1019    public ReplicationStats getReplicationStats(StatsConfig config)
1020        throws DatabaseException {
1021
1022        return dbenv.rep_stat(StatsConfig.checkNull(config).getFlags());
1023    }
1024
1025    /**
1026    Return the database environment's replication manager statistics.
1027    <p>
1028    @param config The statistics attributes.  If null, default attributes are used.
1029    <p>
1030    @return
1031    The database environment's replication manager statistics.
1032    <p>
1033    <p>
1034@throws DatabaseException if a failure occurs.
1035    */
1036    public ReplicationManagerStats getReplicationManagerStats(
1037        StatsConfig config)
1038        throws DatabaseException {
1039
1040        return dbenv.repmgr_stat(StatsConfig.checkNull(config).getFlags());
1041    }
1042
1043    /**
1044    Return the database environment's locking statistics.
1045    <p>
1046    @param config The locking statistics attributes.  If null, default attributes are used.
1047    <p>
1048    @return
1049    The database environment's locking statistics.
1050    <p>
1051    <p>
1052@throws DatabaseException if a failure occurs.
1053    */
1054    public LockStats getLockStats(StatsConfig config)
1055        throws DatabaseException {
1056
1057        return dbenv.lock_stat(StatsConfig.checkNull(config).getFlags());
1058    }
1059
1060    /**
1061    Return the database environment's mutex statistics.
1062    <p>
1063    @param config The statistics attributes.  If null, default attributes are used.
1064    <p>
1065    @return
1066    The database environment's mutex statistics.
1067    <p>
1068    <p>
1069@throws DatabaseException if a failure occurs.
1070    */
1071    public MutexStats getMutexStats(StatsConfig config)
1072        throws DatabaseException {
1073
1074        return dbenv.mutex_stat(StatsConfig.checkNull(config).getFlags());
1075    }
1076
1077    /**
1078    Return the database environment's transactional statistics.
1079    <p>
1080    @param config The transactional statistics attributes.  If null, default attributes are used.
1081    <p>
1082    @return
1083    The database environment's transactional statistics.
1084    <p>
1085    <p>
1086@throws DatabaseException if a failure occurs.
1087    */
1088    public TransactionStats getTransactionStats(StatsConfig config)
1089        throws DatabaseException {
1090
1091        return dbenv.txn_stat(StatsConfig.checkNull(config).getFlags());
1092    }
1093
1094    /* Transaction management */
1095    /**
1096    Allocate a locker ID in an environment configured for Berkeley DB
1097    Concurrent Data Store applications.   Returns a {@link Transaction} object
1098    that uniquely identifies the locker ID.  Calling the {@link
1099    Transaction#commit} method will discard the allocated locker ID.
1100    <p>
1101    See
1102    <a href="{@docRoot}/../ref/cam/intro.html" target="_top">Berkeley DB Concurrent Data Store applications</a>
1103    for more information about when this is required.
1104    <p>
1105    @return
1106    A transaction handle that wraps a CDS locker ID.
1107    */
1108    public Transaction beginCDSGroup() throws DatabaseException {
1109
1110        return new Transaction(dbenv.cdsgroup_begin());
1111    }
1112
1113    /**
1114    Create a new transaction in the database environment.
1115    <p>
1116    Transactions may only span threads if they do so serially; that is,
1117    each transaction must be active in only a single thread of control
1118    at a time.
1119    <p>
1120    This restriction holds for parents of nested transactions as well;
1121    no two children may be concurrently active in more than one thread
1122    of control at any one time.
1123    <p>
1124    Cursors may not span transactions; that is, each cursor must be opened
1125    and closed within a single transaction.
1126    <p>
1127    A parent transaction may not issue any Berkeley DB operations --
1128    except for {@link com.sleepycat.db.Environment#beginTransaction Environment.beginTransaction},
1129    {@link com.sleepycat.db.Transaction#abort Transaction.abort} and {@link com.sleepycat.db.Transaction#commit Transaction.commit} --
1130    while it has active child transactions (child transactions that have
1131    not yet been committed or aborted).
1132    <p>
1133    @param parent
1134    If the parent parameter is non-null, the new transaction will be a
1135    nested transaction, with the transaction indicated by parent as its
1136    parent.  Transactions may be nested to any level.  In the presence
1137    of distributed transactions and two-phase commit, only the parental
1138    transaction, that is a transaction without a parent specified,
1139    should be passed as an parameter to {@link com.sleepycat.db.Transaction#prepare Transaction.prepare}.
1140    <p>
1141    @param config
1142    The transaction attributes.  If null, default attributes are used.
1143    <p>
1144    @return
1145    The newly created transaction's handle.
1146    <p>
1147    @throws DatabaseException if a failure occurs.
1148    */
1149    public Transaction beginTransaction(final Transaction parent,
1150                                        TransactionConfig config)
1151        throws DatabaseException {
1152
1153        return new Transaction(
1154            TransactionConfig.checkNull(config).beginTransaction(dbenv,
1155                (parent == null) ? null : parent.txn));
1156    }
1157
1158    /**
1159    Synchronously checkpoint the database environment.
1160    <p>
1161    <p>
1162    @param config
1163    The checkpoint attributes.  If null, default attributes are used.
1164    <p>
1165    @throws DatabaseException if a failure occurs.
1166    */
1167    public void checkpoint(CheckpointConfig config)
1168        throws DatabaseException {
1169
1170        CheckpointConfig.checkNull(config).runCheckpoint(dbenv);
1171    }
1172
1173    /**
1174    Flush log records to stable storage.
1175    <p>
1176    @param lsn
1177    All log records with LogSequenceNumber values less than or equal to
1178    the lsn parameter are written to stable storage.  If lsn is null,
1179    all records in the log are flushed.
1180    <p>
1181    <p>
1182@throws DatabaseException if a failure occurs.
1183    */
1184    public void logFlush(LogSequenceNumber lsn)
1185        throws DatabaseException {
1186
1187        dbenv.log_flush(lsn);
1188    }
1189
1190    /**
1191    Append a record to the log.
1192    <p>
1193    @param data
1194    The record to append to the log.
1195    <p>
1196    The caller is responsible for providing any necessary structure to
1197    data.  (For example, in a write-ahead logging protocol, the
1198    application must understand what part of data is an operation code,
1199    what part is redo information, and what part is undo information.
1200    In addition, most transaction managers will store in data the
1201    LogSequenceNumber of the previous log record for the same
1202    transaction, to support chaining back through the transaction's log
1203    records during undo.)
1204    <p>
1205    @param flush
1206    The log is forced to disk after this record is written, guaranteeing
1207    that all records with LogSequenceNumber values less than or equal
1208    to the one being "put" are on disk before this method returns.
1209    <p>
1210    @return
1211    The LogSequenceNumber of the put record.
1212    <p>
1213    <p>
1214@throws DatabaseException if a failure occurs.
1215    */
1216    public LogSequenceNumber logPut(DatabaseEntry data, boolean flush)
1217        throws DatabaseException {
1218
1219        final LogSequenceNumber lsn = new LogSequenceNumber();
1220        dbenv.log_put(lsn, data, flush ? DbConstants.DB_FLUSH : 0);
1221        return lsn;
1222    }
1223
1224    /**
1225    Append an informational message to the Berkeley DB database environment log files.
1226    <p>
1227    This method allows applications to include information in
1228    the database environment log files, for later review using the
1229    <a href="{@docRoot}/../utility/db_printlog.html" target="_top">db_printlog</a>
1230     utility.  This method is intended for debugging and performance tuning.
1231     <p>
1232    @param txn
1233    If the logged message refers to an application-specified transaction,
1234    the <code>txn</code> parameter is a transaction handle, otherwise
1235    <code>null</code>.
1236    <p>
1237    <p>
1238@throws DatabaseException if a failure occurs.
1239    **/
1240    public void logPrint(Transaction txn, String message)
1241        throws DatabaseException {
1242
1243        dbenv.log_print((txn == null) ? null : txn.txn, message);
1244    }
1245
1246    public java.io.File[] getArchiveLogFiles(boolean includeInUse)
1247        throws DatabaseException {
1248
1249        final String[] logNames = dbenv.log_archive(DbConstants.DB_ARCH_ABS |
1250                (includeInUse ? DbConstants.DB_ARCH_LOG : 0));
1251        final int len = (logNames == null) ? 0 : logNames.length;
1252        final java.io.File[] logFiles = new java.io.File[len];
1253        for (int i = 0; i < len; i++)
1254            logFiles[i] = new java.io.File(logNames[i]);
1255        return logFiles;
1256    }
1257
1258    public java.io.File[] getArchiveDatabases()
1259        throws DatabaseException {
1260
1261        final String home = dbenv.get_home();
1262        final String[] dbNames = dbenv.log_archive(DbConstants.DB_ARCH_DATA);
1263        final int len = (dbNames == null) ? 0 : dbNames.length;
1264        final java.io.File[] dbFiles = new java.io.File[len];
1265        for (int i = 0; i < len; i++)
1266            dbFiles[i] = new java.io.File(home, dbNames[i]);
1267        return dbFiles;
1268    }
1269
1270    /**
1271    Remove log files that are no longer needed.
1272    <p>
1273    Automatic log file removal is likely to make catastrophic recovery
1274    impossible.
1275    <p>
1276    <p>
1277@throws DatabaseException if a failure occurs.
1278    */
1279    public void removeOldLogFiles()
1280        throws DatabaseException {
1281
1282        dbenv.log_archive(DbConstants.DB_ARCH_REMOVE);
1283    }
1284
1285    public PreparedTransaction[] recover(final int count,
1286                                         final boolean continued)
1287        throws DatabaseException {
1288
1289        return dbenv.txn_recover(count,
1290            continued ? DbConstants.DB_NEXT : DbConstants.DB_FIRST);
1291    }
1292
1293    /**
1294    Allows database files to be copied, and then the copy used in the same
1295    database environment as the original.
1296    <p>
1297    All databases contain an ID string used to identify the database in the
1298    database environment cache.  If a physical database file is copied, and
1299    used in the same environment as another file with the same ID strings,
1300    corruption can occur.  This method creates new ID strings for all of
1301    the databases in the physical file.
1302    <p>
1303    This method modifies the physical file, in-place.
1304    Applications should not reset IDs in files that are currently in use.
1305    <p>
1306    This method may be called at any time during the life of the application.
1307    <p>
1308    @param filename
1309    The name of the physical file in which the LSNs are to be cleared.
1310    @param encrypted
1311    Whether the file contains encrypted databases.
1312    <p>
1313@throws DatabaseException if a failure occurs.
1314    */
1315    public void resetFileID(final String filename, boolean encrypted)
1316        throws DatabaseException {
1317
1318        dbenv.fileid_reset(filename, encrypted ? DbConstants.DB_ENCRYPT : 0);
1319    }
1320
1321    /**
1322    Allows database files to be moved from one transactional database
1323    environment to another.
1324    <p>
1325    Database pages in transactional database environments contain references
1326    to the environment's log files (that is, log sequence numbers, or LSNs).
1327    Copying or moving a database file from one database environment to
1328    another, and then modifying it, can result in data corruption if the
1329    LSNs are not first cleared.
1330    <p>
1331    Note that LSNs should be reset before moving or copying the database
1332    file into a new database environment, rather than moving or copying the
1333    database file and then resetting the LSNs.  Berkeley DB has consistency checks
1334    that may be triggered if an application calls this method
1335    on a database in a new environment when the database LSNs still reflect
1336    the old environment.
1337    <p>
1338    This method modifies the physical file, in-place.
1339    Applications should not reset LSNs in files that are currently in use.
1340    <p>
1341    This method may be called at any time during the life of the application.
1342    <p>
1343    @param filename
1344    The name of the physical file in which the LSNs are to be cleared.
1345    @param encrypted
1346    Whether the file contains encrypted databases.
1347    <p>
1348@throws DatabaseException if a failure occurs.
1349    */
1350    public void resetLogSequenceNumber(final String filename, boolean encrypted)
1351        throws DatabaseException {
1352
1353        dbenv.lsn_reset(filename, encrypted ? DbConstants.DB_ENCRYPT : 0);
1354    }
1355
1356    /* Panic the environment, or stop a panic. */
1357    /**
1358    Set the panic state for the database environment.
1359    Database environments in a panic state normally refuse all attempts to
1360    call library functions, throwing a {@link com.sleepycat.db.RunRecoveryException RunRecoveryException}.
1361    <p>
1362    This method configures a database environment, including all threads
1363of control accessing the database environment, not only the operations
1364performed using a specified {@link com.sleepycat.db.Environment Environment} handle.
1365    <p>
1366    This method may be called at any time during the life of the application.
1367    <p>
1368    @param onoff
1369    If true, set the panic state for the database environment.
1370    */
1371    public void panic(boolean onoff)
1372        throws DatabaseException {
1373
1374        dbenv.set_flags(DbConstants.DB_PANIC_ENVIRONMENT, onoff);
1375    }
1376
1377    /* Version information */
1378    /**
1379Return the release version information, suitable for display.
1380<p>
1381This method may be called at any time during the life of the application.
1382<p>
1383@return
1384The release version information, suitable for display.
1385    */
1386    public static String getVersionString() {
1387        return DbEnv.get_version_string();
1388    }
1389
1390    /**
1391Return the release major number.
1392<p>
1393This method may be called at any time during the life of the application.
1394<p>
1395@return
1396The release major number.
1397    */
1398    public static int getVersionMajor() {
1399        return DbEnv.get_version_major();
1400    }
1401
1402    /**
1403Return the release minor number.
1404<p>
1405This method may be called at any time during the life of the application.
1406<p>
1407@return
1408The release minor number.
1409    */
1410    public static int getVersionMinor() {
1411        return DbEnv.get_version_minor();
1412    }
1413
1414    /**
1415Return the release patch number.
1416<p>
1417This method may be called at any time during the life of the application.
1418<p>
1419@return
1420The release patch number.
1421    */
1422    public static int getVersionPatch() {
1423        return DbEnv.get_version_patch();
1424    }
1425}
1426