1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 */ 7using System; 8using System.Collections.Generic; 9using System.Text; 10 11using BerkeleyDB.Internal; 12 13namespace BerkeleyDB { 14 /// <summary> 15 /// A class representing configuration parameters for 16 /// <see cref="BTreeDatabase"/> 17 /// </summary> 18 public class BTreeDatabaseConfig : DatabaseConfig { 19 /* Fields for DB->set_flags() */ 20 /// <summary> 21 /// Policy for duplicate data items in the database; that is, insertion 22 /// when the key of the key/data pair being inserted already exists in 23 /// the database will be successful. 24 /// </summary> 25 /// <remarks> 26 /// <para>The ordering of duplicates in the database for 27 /// <see cref="DuplicatesPolicy.UNSORTED"/> is determined by the order 28 /// of insertion, unless the ordering is otherwise specified by use of a 29 /// cursor operation or a duplicate sort function. The ordering of 30 /// duplicates in the database for 31 /// <see cref="DuplicatesPolicy.SORTED"/> is determined by the 32 /// duplicate comparison function. If the application does not specify a 33 /// comparison function using 34 /// <see cref="DuplicateCompare"/>, a default lexical 35 /// comparison will be used. 36 /// </para> 37 /// <para> 38 /// <see cref="DuplicatesPolicy.SORTED"/> is preferred to 39 /// <see cref="DuplicatesPolicy.UNSORTED"/> for performance reasons. 40 /// <see cref="DuplicatesPolicy.UNSORTED"/> should only be used by 41 /// applications wanting to order duplicate data items manually. 42 /// </para> 43 /// <para> 44 /// If the database already exists, the value of Duplicates must be the 45 /// same as the existing database or an error will be returned. 46 /// </para> 47 /// <para> 48 /// It is an error to specify <see cref="UseRecordNumbers"/> and 49 /// anything other than <see cref="DuplicatesPolicy.NONE"/>. 50 /// </para> 51 /// </remarks> 52 public DuplicatesPolicy Duplicates; 53 /// <summary> 54 /// Turn reverse splitting in the Btree on or off. 55 /// </summary> 56 /// <remarks> 57 /// As pages are emptied in a database, the Berkeley DB Btree 58 /// implementation attempts to coalesce empty pages into higher-level 59 /// pages in order to keep the database as small as possible and 60 /// minimize search time. This can hurt performance in applications with 61 /// cyclical data demands; that is, applications where the database 62 /// grows and shrinks repeatedly. For example, because Berkeley DB does 63 /// page-level locking, the maximum level of concurrency in a database 64 /// of two pages is far smaller than that in a database of 100 pages, so 65 /// a database that has shrunk to a minimal size can cause severe 66 /// deadlocking when a new cycle of data insertion begins. 67 /// </remarks> 68 public bool NoReverseSplitting; 69 /// <summary> 70 /// If true, support retrieval from the Btree using record numbers. 71 /// </summary> 72 /// <remarks> 73 /// <para> 74 /// Logical record numbers in Btree databases are mutable in the face of 75 /// record insertion or deletion. See 76 /// <see cref="RecnoDatabaseConfig.Renumber"/> for further discussion. 77 /// </para> 78 /// <para> 79 /// Maintaining record counts within a Btree introduces a serious point 80 /// of contention, namely the page locations where the record counts are 81 /// stored. In addition, the entire database must be locked during both 82 /// insertions and deletions, effectively single-threading the database 83 /// for those operations. Specifying UseRecordNumbers can result in 84 /// serious performance degradation for some applications and data sets. 85 /// </para> 86 /// <para> 87 /// It is an error to specify <see cref="UseRecordNumbers"/> and 88 /// anything other than <see cref="DuplicatesPolicy.NONE"/>. 89 /// </para> 90 /// <para> 91 /// If the database already exists, the value of UseRecordNumbers must 92 /// be the same as the existing database or an error will be returned. 93 /// </para> 94 /// </remarks> 95 public bool UseRecordNumbers; 96 internal new uint flags { 97 get { 98 uint ret = base.flags; 99 ret |= (uint)Duplicates; 100 ret |= NoReverseSplitting ? 101 Internal.DbConstants.DB_REVSPLITOFF : 0; 102 ret |= UseRecordNumbers ? Internal.DbConstants.DB_RECNUM : 0; 103 return ret; 104 } 105 } 106 107 /// <summary> 108 /// The policy for how to handle database creation. 109 /// </summary> 110 /// <remarks> 111 /// If the database does not already exist and 112 /// <see cref="CreatePolicy.NEVER"/> is set, 113 /// <see cref="BTreeDatabase.Open"/> will fail. 114 /// </remarks> 115 public CreatePolicy Creation; 116 internal new uint openFlags { 117 get { 118 uint flags = base.openFlags; 119 flags |= (uint)Creation; 120 return flags; 121 } 122 } 123 124 /// <summary> 125 /// The Btree key comparison function. 126 /// </summary> 127 /// <remarks> 128 /// <para> 129 /// The comparison function is called whenever it is necessary to 130 /// compare a key specified by the application with a key currently 131 /// stored in the tree. 132 /// </para> 133 /// <para> 134 /// If no comparison function is specified, the keys are compared 135 /// lexically, with shorter keys collating before longer keys. 136 /// </para> 137 /// <para> 138 /// If the database already exists, the comparison function must be the 139 /// same as that historically used to create the database or corruption 140 /// can occur. 141 /// </para> 142 /// </remarks> 143 public EntryComparisonDelegate BTreeCompare; 144 /// <summary> 145 /// The Btree prefix function. 146 /// </summary> 147 /// <remarks> 148 /// <para> 149 /// The prefix function is used to determine the amount by which keys 150 /// stored on the Btree internal pages can be safely truncated without 151 /// losing their uniqueness. See the Btree prefix comparison section of 152 /// the Berkeley DB Reference Guide for more details about how this 153 /// works. The usefulness of this is data-dependent, but can produce 154 /// significantly reduced tree sizes and search times in some data sets. 155 /// </para> 156 /// <para> 157 /// If no prefix function or key comparison function is specified by the 158 /// application, a default lexical comparison function is used as the 159 /// prefix function. If no prefix function is specified and 160 /// <see cref="BTreeCompare"/> is specified, no prefix function is 161 /// used. It is an error to specify a prefix function without also 162 /// specifying <see cref="BTreeCompare"/>. 163 /// </para> 164 /// <para> 165 /// If the database already exists, the prefix function must be the 166 /// same as that historically used to create the database or corruption 167 /// can occur. 168 /// </para> 169 /// </remarks> 170 public EntryComparisonDelegate BTreePrefixCompare; 171 /// <summary> 172 /// The duplicate data item comparison function. 173 /// </summary> 174 /// <remarks> 175 /// <para> 176 /// The comparison function is called whenever it is necessary to 177 /// compare a data item specified by the application with a data item 178 /// currently stored in the database. Setting DuplicateCompare implies 179 /// setting <see cref="Duplicates"/> to 180 /// <see cref="DuplicatesPolicy.SORTED"/>. 181 /// </para> 182 /// <para> 183 /// If no comparison function is specified, the data items are compared 184 /// lexically, with shorter data items collating before longer data 185 /// items. 186 /// </para> 187 /// <para> 188 /// If the database already exists when 189 /// <see cref="BTreeDatabase.Open"/> is called, the 190 /// delegate must be the same as that historically used to create the 191 /// database or corruption can occur. 192 /// </para> 193 /// </remarks> 194 public EntryComparisonDelegate DuplicateCompare; 195 196 internal bool compressionIsSet; 197 private BTreeCompressDelegate compressFunc; 198 /// <summary> 199 /// The compression function used to store key/data pairs in the 200 /// database. 201 /// </summary> 202 public BTreeCompressDelegate Compress { get { return compressFunc; } } 203 private BTreeDecompressDelegate decompressFunc; 204 /// <summary> 205 /// The decompression function used to retrieve key/data pairs from the 206 /// database. 207 /// </summary> 208 public BTreeDecompressDelegate Decompress { 209 get { return decompressFunc; } 210 } 211 /// <summary> 212 /// Enable compression of the key/data pairs stored in the database, 213 /// using the default compression and decompression functions. 214 /// </summary> 215 /// <remarks> 216 /// The default functions perform prefix compression on keys, and prefix 217 /// compression on data items for duplicate keys. 218 /// </remarks> 219 public void SetCompression() { 220 compressionIsSet = true; 221 compressFunc = null; 222 decompressFunc = null; 223 } 224 /// <summary> 225 /// Enable compression of the key/data pairs stored in the database, 226 /// using the specified compression and decompression functions. 227 /// </summary> 228 /// <param name="compression">The compression function</param> 229 /// <param name="decompression">The decompression function</param> 230 public void SetCompression(BTreeCompressDelegate compression, 231 BTreeDecompressDelegate decompression) { 232 compressionIsSet = true; 233 compressFunc = compression; 234 decompressFunc = decompression; 235 } 236 237 internal bool minkeysIsSet; 238 private uint minKeys; 239 /// <summary> 240 /// The minimum number of key/data pairs intended to be stored on any 241 /// single Btree leaf page. 242 /// </summary> 243 /// <remarks> 244 /// <para> 245 /// This value is used to determine if key or data items will be stored 246 /// on overflow pages instead of Btree leaf pages. For more information 247 /// on the specific algorithm used, see the Berkeley DB Reference Guide. 248 /// The value specified must be at least 2; if not explicitly set, a 249 /// value of 2 is used. 250 /// </para> 251 /// <para> 252 /// If the database already exists, MinKeysPerPage will be ignored. 253 /// </para> 254 /// </remarks> 255 public uint MinKeysPerPage { 256 get { return minKeys; } 257 set { 258 minkeysIsSet = true; 259 minKeys = value; 260 } 261 } 262 263 /// <summary> 264 /// Create a new BTreeDatabaseConfig object 265 /// </summary> 266 public BTreeDatabaseConfig() { 267 Duplicates = DuplicatesPolicy.NONE; 268 NoReverseSplitting = false; 269 UseRecordNumbers = false; 270 271 BTreeCompare = null; 272 BTreePrefixCompare = null; 273 274 minkeysIsSet = false; 275 276 Creation = CreatePolicy.NEVER; 277 } 278 } 279} 280