/*- * 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 } }