/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2009 Oracle. All rights reserved.
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using BerkeleyDB.Internal;
namespace BerkeleyDB {
///
/// A class representing a QueueDatabase. The Queue format supports fast
/// access to fixed-length records accessed sequentially or by logical
/// record number.
///
public class QueueDatabase : Database {
#region Constructors
private QueueDatabase(DatabaseEnvironment env, uint flags)
: base(env, flags) { }
internal QueueDatabase(BaseDatabase clone) : base(clone) { }
private void Config(QueueDatabaseConfig cfg) {
base.Config(cfg);
/*
* Database.Config calls set_flags, but that doesn't get the Queue
* specific flags. No harm in calling it again.
*/
db.set_flags(cfg.flags);
db.set_re_len(cfg.Length);
if (cfg.padIsSet)
db.set_re_pad(cfg.PadByte);
if (cfg.extentIsSet)
db.set_q_extentsize(cfg.ExtentSize);
}
///
/// Instantiate a new QueueDatabase object and open the database
/// represented by .
///
///
///
/// If is null, the database is strictly
/// temporary and cannot be opened by any other thread of control, thus
/// the database can only be accessed by sharing the single database
/// object that created it, in circumstances where doing so is safe.
///
///
/// If is set, the operation
/// will be implicitly transaction protected. Note that transactionally
/// protected operations on a datbase object requires the object itself
/// be transactionally protected during its open.
///
///
///
/// The name of an underlying file that will be used to back the
/// database. In-memory databases never intended to be preserved on disk
/// may be created by setting this parameter to null.
///
/// The database's configuration
/// A new, open database object
public static QueueDatabase Open(
string Filename, QueueDatabaseConfig cfg) {
return Open(Filename, cfg, null);
}
///
/// Instantiate a new QueueDatabase object and open the database
/// represented by .
///
///
///
/// If is null, the database is strictly
/// temporary and cannot be opened by any other thread of control, thus
/// the database can only be accessed by sharing the single database
/// object that created it, in circumstances where doing so is safe.
///
///
/// If is null, but
/// is set, the operation will
/// be implicitly transaction protected. Note that transactionally
/// protected operations on a datbase object requires the object itself
/// be transactionally protected during its open. Also note that the
/// transaction must be committed before the object is closed.
///
///
///
/// The name of an underlying file that will be used to back the
/// database. In-memory databases never intended to be preserved on disk
/// may be created by setting this parameter to null.
///
/// The database's configuration
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// A new, open database object
public static QueueDatabase Open(
string Filename, QueueDatabaseConfig cfg, Transaction txn) {
QueueDatabase ret = new QueueDatabase(cfg.Env, 0);
ret.Config(cfg);
ret.db.open(Transaction.getDB_TXN(txn),
Filename, null, DBTYPE.DB_QUEUE, cfg.openFlags, 0);
ret.isOpen = true;
return ret;
}
#endregion Constructors
#region Properties
///
/// The size of the extents used to hold pages in a
/// , specified as a number of pages.
///
public uint ExtentSize {
get {
uint ret = 0;
db.get_q_extentsize(ref ret);
return ret;
}
}
///
/// If true, modify the operation of
/// to return key/data pairs in order. That is, they will always return
/// the key/data item from the head of the queue.
///
public bool InOrder {
get {
uint flags = 0;
db.get_flags(ref flags);
return (flags & DbConstants.DB_INORDER) != 0;
}
}
///
/// The length of records in the database.
///
public uint Length {
get {
uint ret = 0;
db.get_re_len(ref ret);
return ret;
}
}
///
/// The padding character for short, fixed-length records.
///
public int PadByte {
get {
int ret = 0;
db.get_re_pad(ref ret);
return ret;
}
}
#endregion Properties
#region Methods
///
/// Append the data item to the end of the database.
///
/// The data item to store in the database
/// The record number allocated to the record
public uint Append(DatabaseEntry data) {
return Append(data, null);
}
///
/// Append the data item to the end of the database.
///
///
/// There is a minor behavioral difference between
/// and
/// . If a transaction enclosing an
/// Append operation aborts, the record number may be reallocated in a
/// subsequent operation, but it will
/// not be reallocated in a subsequent
/// operation.
///
/// The data item to store in the database
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// The record number allocated to the record
public uint Append(DatabaseEntry data, Transaction txn) {
DatabaseEntry key = new DatabaseEntry();
Put(key, data, txn, DbConstants.DB_APPEND);
return BitConverter.ToUInt32(key.Data, 0);
}
///
/// Return the record number and data from the available record closest
/// to the head of the queue, and delete the record.
///
///
/// If true and the Queue database is empty, the thread of control will
/// wait until there is data in the queue before returning.
///
///
/// If lock or transaction timeouts have been specified, a
/// may be thrown. This failure,
/// by itself, does not require the enclosing transaction be aborted.
///
///
/// A whose Key
/// parameter is the record number and whose Value parameter is the
/// retrieved data.
///
public KeyValuePair Consume(bool wait) {
return Consume(wait, null, null);
}
///
/// Return the record number and data from the available record closest
/// to the head of the queue, and delete the record.
///
///
/// If true and the Queue database is empty, the thread of control will
/// wait until there is data in the queue before returning.
///
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// If lock or transaction timeouts have been specified, a
/// may be thrown. This failure,
/// by itself, does not require the enclosing transaction be aborted.
///
///
/// A whose Key
/// parameter is the record number and whose Value parameter is the
/// retrieved data.
///
public KeyValuePair Consume(
bool wait, Transaction txn) {
return Consume(wait, txn, null);
}
///
/// Return the record number and data from the available record closest
/// to the head of the queue, and delete the record.
///
///
/// If true and the Queue database is empty, the thread of control will
/// wait until there is data in the queue before returning.
///
///
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// The locking behavior to use.
///
/// If lock or transaction timeouts have been specified, a
/// may be thrown. This failure,
/// by itself, does not require the enclosing transaction be aborted.
///
///
/// A whose Key
/// parameter is the record number and whose Value parameter is the
/// retrieved data.
///
public KeyValuePair Consume(
bool wait, Transaction txn, LockingInfo info) {
KeyValuePair record;
record = Get(null, null, txn, info,
wait ? DbConstants.DB_CONSUME_WAIT : DbConstants.DB_CONSUME);
return new KeyValuePair(
BitConverter.ToUInt32(record.Key.Data, 0), record.Value);
}
///
/// Return the database statistical information which does not require
/// traversal of the database.
///
///
/// The database statistical information which does not require
/// traversal of the database.
///
public QueueStats FastStats() {
return Stats(null, true, Isolation.DEGREE_THREE);
}
///
/// Return the database statistical information which does not require
/// traversal of the database.
///
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// The database statistical information which does not require
/// traversal of the database.
///
public QueueStats FastStats(Transaction txn) {
return Stats(txn, true, Isolation.DEGREE_THREE);
}
///
/// Return the database statistical information which does not require
/// traversal of the database.
///
///
///
/// Among other things, this method makes it possible for applications
/// to request key and record counts without incurring the performance
/// penalty of traversing the entire database.
///
///
/// The statistical information is described by the
/// , ,
/// , and classes.
///
///
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// The level of isolation for database reads.
/// will be silently ignored for
/// databases which did not specify
/// .
///
///
/// The database statistical information which does not require
/// traversal of the database.
///
public QueueStats FastStats(Transaction txn, Isolation isoDegree) {
return Stats(txn, true, isoDegree);
}
///
/// Return the database statistical information for this database.
///
/// Database statistical information.
public QueueStats Stats() {
return Stats(null, false, Isolation.DEGREE_THREE);
}
///
/// Return the database statistical information for this database.
///
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
/// Database statistical information.
public QueueStats Stats(Transaction txn) {
return Stats(txn, false, Isolation.DEGREE_THREE);
}
///
/// Return the database statistical information for this database.
///
///
/// The statistical information is described by
/// .
///
///
/// If the operation is part of an application-specified transaction,
/// is a Transaction object returned from
/// ; if
/// the operation is part of a Berkeley DB Concurrent Data Store group,
/// is a handle returned from
/// ; otherwise null.
///
///
/// The level of isolation for database reads.
/// will be silently ignored for
/// databases which did not specify
/// .
///
/// Database statistical information.
public QueueStats Stats(Transaction txn, Isolation isoDegree) {
return Stats(txn, false, isoDegree);
}
private QueueStats Stats(Transaction txn, bool fast, Isolation isoDegree) {
uint flags = 0;
flags |= fast ? DbConstants.DB_FAST_STAT : 0;
switch (isoDegree) {
case Isolation.DEGREE_ONE:
flags |= DbConstants.DB_READ_UNCOMMITTED;
break;
case Isolation.DEGREE_TWO:
flags |= DbConstants.DB_READ_COMMITTED;
break;
}
QueueStatStruct st = db.stat_qam(Transaction.getDB_TXN(txn), flags);
return new QueueStats(st);
}
#endregion Methods
}
}