1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2011, 2013 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 using System;
8 using System.Collections.Generic;
9 using System.Text;
10 using BerkeleyDB.Internal;
11 
12 namespace BerkeleyDB {
13     /// <summary>
14     /// A class representing a HeapDatabase.
15     /// </summary>
16     public class HeapDatabase : Database {
17 
18         #region Constructors
HeapDatabase(DatabaseEnvironment env, uint flags)19         private HeapDatabase(DatabaseEnvironment env, uint flags)
20             : base(env, flags) { }
HeapDatabase(BaseDatabase clone)21         internal HeapDatabase(BaseDatabase clone) : base(clone) { }
22 
Config(HeapDatabaseConfig cfg)23         private void Config(HeapDatabaseConfig cfg) {
24             base.Config(cfg);
25             /*
26              * Database.Config calls set_flags, but that doesn't get the Heap
27              * specific flags.  No harm in calling it again.
28              */
29             db.set_flags(cfg.flags);
30 
31             if (cfg.maxSizeIsSet)
32                 db.set_heapsize(cfg.MaxSizeGBytes, cfg.MaxSizeBytes);
33             if (cfg.regionszIsSet)
34                 db.set_heap_regionsize(cfg.RegionSize);
35         }
36 
37         /// <summary>
38         /// Instantiate a new HeapDatabase object and open the database
39         /// represented by <paramref name="Filename"/>.
40         /// </summary>
41         /// <remarks>
42         /// <para>
43         /// If <paramref name="Filename"/> is null, the database is strictly
44         /// temporary and cannot be opened by any other thread of control, thus
45         /// the database can only be accessed by sharing the single database
46         /// object that created it, in circumstances where doing so is safe.
47         /// </para>
48         /// <para>
49         /// If <see cref="DatabaseConfig.AutoCommit"/> is set, the operation
50         /// will be implicitly transaction protected. Note that transactionally
51         /// protected operations on a datbase object requires the object itself
52         /// be transactionally protected during its open.
53         /// </para>
54         /// </remarks>
55         /// <param name="Filename">
56         /// The name of an underlying file that will be used to back the
57         /// database. In-memory databases never intended to be preserved on disk
58         /// may be created by setting this parameter to null.
59         /// </param>
60         /// <param name="cfg">The database's configuration</param>
61         /// <returns>A new, open database object</returns>
Open( string Filename, HeapDatabaseConfig cfg)62         public static HeapDatabase Open(
63             string Filename, HeapDatabaseConfig cfg) {
64             return Open(Filename, cfg, null);
65         }
66         /// <summary>
67         /// Instantiate a new HeapDatabase object and open the database
68         /// represented by <paramref name="Filename"/>.
69         /// </summary>
70         /// <remarks>
71         /// <para>
72         /// If <paramref name="Filename"/> is null, the database is strictly
73         /// temporary and cannot be opened by any other thread of control, thus
74         /// the database can only be accessed by sharing the single database
75         /// object that created it, in circumstances where doing so is safe.
76         /// </para>
77         /// <para>
78         /// If <paramref name="txn"/> is null, but
79         /// <see cref="DatabaseConfig.AutoCommit"/> is set, the operation will
80         /// be implicitly transaction protected. Note that transactionally
81         /// protected operations on a datbase object requires the object itself
82         /// be transactionally protected during its open. Also note that the
83         /// transaction must be committed before the object is closed.
84         /// </para>
85         /// </remarks>
86         /// <param name="Filename">
87         /// The name of an underlying file that will be used to back the
88         /// database. In-memory databases never intended to be preserved on disk
89         /// may be created by setting this parameter to null.
90         /// </param>
91         /// <param name="cfg">The database's configuration</param>
92         /// <param name="txn">
93         /// If the operation is part of an application-specified transaction,
94         /// <paramref name="txn"/> is a Transaction object returned from
95         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
96         /// the operation is part of a Berkeley DB Concurrent Data Store group,
97         /// <paramref name="txn"/> is a handle returned from
98         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
99         /// </param>
100         /// <returns>A new, open database object</returns>
Open( string Filename, HeapDatabaseConfig cfg, Transaction txn)101         public static HeapDatabase Open(
102             string Filename, HeapDatabaseConfig cfg, Transaction txn) {
103             HeapDatabase ret = new HeapDatabase(cfg.Env, 0);
104             ret.Config(cfg);
105             ret.db.open(Transaction.getDB_TXN(txn),
106                 Filename, null, DBTYPE.DB_HEAP, cfg.openFlags, 0);
107             ret.isOpen = true;
108             return ret;
109         }
110 
111         #endregion Constructors
112 
113         #region Properties
114         /// <summary>
115         /// The gigabytes component of the maximum on-disk database file size.
116         /// </summary>
117         public uint MaxSizeGBytes {
118             get {
119                 uint gbytes = 0;
120                 uint bytes = 0;
121                 db.get_heapsize(ref gbytes, ref bytes);
122                 return gbytes;
123             }
124         }
125         /// <summary>
126         /// The bytes component of the maximum on-disk database file size.
127         /// </summary>
128         public uint MaxSizeBytes {
129             get {
130                 uint gbytes = 0;
131                 uint bytes = 0;
132                 db.get_heapsize(ref gbytes, ref bytes);
133                 return bytes;
134             }
135         }
136         /// <summary>
137         /// The number of pages in a region of the database. It is set by
138         /// <see cref="HeapDatabaseConfig.RegionSize"/> when the heap database
139         /// is opened.
140         /// </summary>
141         public uint RegionSize {
142             get {
143                  uint ret = 0;
144                  db.get_heap_regionsize(ref ret);
145                  return ret;
146             }
147         }
148         #endregion Properties
149 
150         #region Methods
151         /// <summary>
152         /// Append the data item to the end of the database.
153         /// </summary>
154         /// <param name="data">The data item to store in the database</param>
155         /// <returns>The heap record id allocated to the record</returns>
Append(DatabaseEntry data)156         public HeapRecordId Append(DatabaseEntry data) {
157             return Append(data, null);
158         }
159         /// <summary>
160         /// Append the data item to the end of the database.
161         /// </summary>
162         /// <param name="data">The data item to store in the database</param>
163         /// <param name="txn">
164         /// If the operation is part of an application-specified transaction,
165         /// <paramref name="txn"/> is a Transaction object returned from
166         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
167         /// the operation is part of a Berkeley DB Concurrent Data Store group,
168         /// <paramref name="txn"/> is a handle returned from
169         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
170         /// </param>
171         /// <returns>The heap record id allocated to the record</returns>
Append(DatabaseEntry data, Transaction txn)172         public HeapRecordId Append(DatabaseEntry data, Transaction txn) {
173             DatabaseEntry key = new DatabaseEntry();
174             Put(key, data, txn, DbConstants.DB_APPEND);
175             return HeapRecordId.fromArray(key.Data);
176         }
177 
178         /// <summary>
179         /// Return the database statistical information which does not require
180         /// traversal of the database.
181         /// </summary>
182         /// <returns>
183         /// The database statistical information which does not require
184         /// traversal of the database.
185         /// </returns>
FastStats()186         public HeapStats FastStats() {
187             return Stats(null, true, Isolation.DEGREE_THREE);
188         }
189         /// <summary>
190         /// Return the database statistical information which does not require
191         /// traversal of the database.
192         /// </summary>
193         /// <param name="txn">
194         /// If the operation is part of an application-specified transaction,
195         /// <paramref name="txn"/> is a Transaction object returned from
196         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
197         /// the operation is part of a Berkeley DB Concurrent Data Store group,
198         /// <paramref name="txn"/> is a handle returned from
199         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
200         /// </param>
201         /// <returns>
202         /// The database statistical information which does not require
203         /// traversal of the database.
204         /// </returns>
FastStats(Transaction txn)205         public HeapStats FastStats(Transaction txn) {
206             return Stats(txn, true, Isolation.DEGREE_THREE);
207         }
208         /// <summary>
209         /// Return the database statistical information which does not require
210         /// traversal of the database.
211         /// </summary>
212         /// <overloads>
213         /// <para>
214         /// Among other things, this method makes it possible for applications
215         /// to request key and record counts without incurring the performance
216         /// penalty of traversing the entire database.
217         /// </para>
218         /// <para>
219         /// The statistical information is described by the
220         /// <see cref="BTreeStats"/>, <see cref="HashStats"/>,
221         /// <see cref="HeapStats"/>, <see cref="QueueStats"/>, and
222         /// <see cref="RecnoStats"/> classes.
223         /// </para>
224         /// </overloads>
225         /// <param name="txn">
226         /// If the operation is part of an application-specified transaction,
227         /// <paramref name="txn"/> is a Transaction object returned from
228         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
229         /// the operation is part of a Berkeley DB Concurrent Data Store group,
230         /// <paramref name="txn"/> is a handle returned from
231         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
232         /// </param>
233         /// <param name="isoDegree">
234         /// The level of isolation for database reads.
235         /// <see cref="Isolation.DEGREE_ONE"/> will be silently ignored for
236         /// databases which did not specify
237         /// <see cref="DatabaseConfig.ReadUncommitted"/>.
238         /// </param>
239         /// <returns>
240         /// The database statistical information which does not require
241         /// traversal of the database.
242         /// </returns>
FastStats(Transaction txn, Isolation isoDegree)243         public HeapStats FastStats(Transaction txn, Isolation isoDegree) {
244             return Stats(txn, true, isoDegree);
245         }
246 
247         /// <summary>
248         /// Return the database statistical information for this database.
249         /// </summary>
250         /// <returns>Database statistical information.</returns>
Stats()251         public HeapStats Stats() {
252             return Stats(null, false, Isolation.DEGREE_THREE);
253         }
254         /// <summary>
255         /// Return the database statistical information for this database.
256         /// </summary>
257         /// <param name="txn">
258         /// If the operation is part of an application-specified transaction,
259         /// <paramref name="txn"/> is a Transaction object returned from
260         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
261         /// the operation is part of a Berkeley DB Concurrent Data Store group,
262         /// <paramref name="txn"/> is a handle returned from
263         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
264         /// </param>
265         /// <returns>Database statistical information.</returns>
Stats(Transaction txn)266         public HeapStats Stats(Transaction txn) {
267             return Stats(txn, false, Isolation.DEGREE_THREE);
268         }
269         /// <summary>
270         /// Return the database statistical information for this database.
271         /// </summary>
272         /// <overloads>
273         /// The statistical information is described by
274         /// <see cref="HeapStats"/>.
275         /// </overloads>
276         /// <param name="txn">
277         /// If the operation is part of an application-specified transaction,
278         /// <paramref name="txn"/> is a Transaction object returned from
279         /// <see cref="DatabaseEnvironment.BeginTransaction"/>; if
280         /// the operation is part of a Berkeley DB Concurrent Data Store group,
281         /// <paramref name="txn"/> is a handle returned from
282         /// <see cref="DatabaseEnvironment.BeginCDSGroup"/>; otherwise null.
283         /// </param>
284         /// <param name="isoDegree">
285         /// The level of isolation for database reads.
286         /// <see cref="Isolation.DEGREE_ONE"/> will be silently ignored for
287         /// databases which did not specify
288         /// <see cref="DatabaseConfig.ReadUncommitted"/>.
289         /// </param>
290         /// <returns>Database statistical information.</returns>
Stats(Transaction txn, Isolation isoDegree)291         public HeapStats Stats(Transaction txn, Isolation isoDegree) {
292             return Stats(txn, false, isoDegree);
293         }
Stats(Transaction txn, bool fast, Isolation isoDegree)294         private HeapStats Stats(Transaction txn, bool fast, Isolation isoDegree) {
295             uint flags = 0;
296             flags |= fast ? DbConstants.DB_FAST_STAT : 0;
297             switch (isoDegree) {
298                 case Isolation.DEGREE_ONE:
299                     flags |= DbConstants.DB_READ_UNCOMMITTED;
300                     break;
301                 case Isolation.DEGREE_TWO:
302                     flags |= DbConstants.DB_READ_COMMITTED;
303                     break;
304             }
305             HeapStatStruct st = db.stat_heap(Transaction.getDB_TXN(txn), flags);
306             return new HeapStats(st);
307         }
308         #endregion Methods
309     }
310 }
311