1 /*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002, 2014 Oracle and/or its affiliates. All rights reserved. 5 * 6 */ 7 8 package com.sleepycat.je; 9 10 import java.util.Arrays; 11 import java.util.Comparator; 12 import java.util.HashSet; 13 import java.util.LinkedList; 14 import java.util.List; 15 import java.util.Set; 16 17 import com.sleepycat.je.dbi.DatabaseImpl; 18 import com.sleepycat.je.trigger.ReplicatedDatabaseTrigger; 19 import com.sleepycat.je.trigger.PersistentTrigger; 20 import com.sleepycat.je.trigger.Trigger; 21 22 /** 23 * <p>Specifies the attributes of a database.</p> 24 * 25 * <p>There are two groups of database attributes: per-database handle 26 * attributes, and database-wide attributes. An attribute may be 27 * persistent/transient or mutable/immutable:</p> 28 * 29 * <table border="true"> 30 * <tr> 31 * <td>Scope</td> 32 * <td>Mutable</td> 33 * <td>Persistent</td> 34 * <td>Attribute</td> 35 * </tr> 36 * <tr> 37 * <td rowspan="4">Database-wide attribute</td> 38 * <td>True</td> 39 * <td>True</td> 40 * <td>{@link DatabaseConfig#getBtreeComparator() btree comparator}<br> 41 * {@link DatabaseConfig#getDuplicateComparator() duplicate comparator}<br> 42 * {@link DatabaseConfig#getKeyPrefixing() key prefixing}<br> 43 * {@link DatabaseConfig#getNodeMaxEntries() nodeMaxEntries}<br> 44 * <!-- 45 * {@link DatabaseConfig#getTriggers() triggers}<br></td> 46 * --> 47 * </tr> 48 * <tr> 49 * <td>True</td> 50 * <td>False</td> 51 * <td>{@link DatabaseConfig#getDeferredWrite() deferred write}<br> 52 * {@link DatabaseConfig#getTransactional() transactional}<br></td> 53 * </tr> 54 * <tr> 55 * <td>False</td> 56 * <td>True</td> 57 * <td> 58 * {@link DatabaseConfig#getSortedDuplicates() sorted duplicates}<br> 59 * </td> 60 * </tr> 61 * <tr> 62 * <td>False</td> 63 * <td>False</td> 64 * <td>{@link DatabaseConfig#getTemporary() temporary}</td> 65 * </tr> 66 * <tr> 67 * <td>Per-database handle attributes</td> 68 * <td>False</td> 69 * <td>False</td> 70 * <td>{@link DatabaseConfig#getAllowCreate() allow create}<br> 71 * {@link DatabaseConfig#getExclusiveCreate() exclusive create}<br> 72 * {@link DatabaseConfig#getReadOnly() read only}<br> 73 * {@link DatabaseConfig#getUseExistingConfig() use existing config}<br> 74 * </td> 75 * </tr> 76 * </table> 77 * </p> 78 * 79 * <p>Persistent attributes will be saved in the log and remain in effect 80 * every time the environment is reopened. Transient attributes only remain 81 * in effect until:</p> 82 * 83 * <ul> 84 * <li>the database configuration is updated</li> 85 * <li>the database handle(per-database handle attributes) is closed, or all 86 * handles for this database (database-wide attributes) are closed.</li> 87 * </ul> 88 */ 89 public class DatabaseConfig implements Cloneable { 90 91 /** 92 * An instance created using the default constructor is initialized with 93 * the system's default settings. 94 */ 95 public static final DatabaseConfig DEFAULT = new DatabaseConfig(); 96 97 private boolean allowCreate = false; 98 private boolean exclusiveCreate = false; 99 private boolean transactional = false; 100 private boolean readOnly = false; 101 private boolean sortedDuplicates = false; 102 private boolean deferredWrite = false; 103 private boolean temporary = false; 104 private boolean keyPrefixing = false; 105 private boolean replicated = true; 106 107 private int nodeMaxEntries; 108 private Comparator<byte[]> btreeComparator = null; 109 private Comparator<byte[]> duplicateComparator = null; 110 private boolean btreeComparatorByClassName = false; 111 private boolean duplicateComparatorByClassName = false; 112 private boolean overrideBtreeComparator = false; 113 private boolean overrideDuplicateComparator = false; 114 private boolean useExistingConfig = false; 115 private CacheMode cacheMode = null; 116 private CacheModeStrategy cacheModeStrategy = null; 117 private SecondaryAssociation secAssociation = null; 118 119 /* User defined triggers associated with this database. */ 120 private List<Trigger> triggers = new LinkedList<Trigger>(); 121 private boolean overrideTriggers; 122 123 /** 124 * An instance created using the default constructor is initialized with 125 * the system's default settings. 126 */ DatabaseConfig()127 public DatabaseConfig() { 128 } 129 130 /** 131 * Configures the {@link com.sleepycat.je.Environment#openDatabase 132 * Environment.openDatabase} method to create the database if it does not 133 * already exist. 134 * 135 * @param allowCreate If true, configure the {@link 136 * com.sleepycat.je.Environment#openDatabase Environment.openDatabase} 137 * method to create the database if it does not already exist. 138 * 139 * @return this 140 */ setAllowCreate(boolean allowCreate)141 public DatabaseConfig setAllowCreate(boolean allowCreate) { 142 setAllowCreateVoid(allowCreate); 143 return this; 144 } 145 146 /** 147 * @hidden 148 * The void return setter for use by Bean editors. 149 */ setAllowCreateVoid(boolean allowCreate)150 public void setAllowCreateVoid(boolean allowCreate) { 151 this.allowCreate = allowCreate; 152 } 153 154 /** 155 * Returns true if the {@link com.sleepycat.je.Environment#openDatabase 156 * Environment.openDatabase} method is configured to create the database 157 * if it does not already exist. 158 * 159 * <p>This method may be called at any time during the life of the 160 * application.</p> 161 * 162 * @return true if the {@link com.sleepycat.je.Environment#openDatabase 163 * Environment.openDatabase} method is configured to create the database 164 * if it does not already exist. 165 */ getAllowCreate()166 public boolean getAllowCreate() { 167 return allowCreate; 168 } 169 170 /** 171 * Configure the {@link com.sleepycat.je.Environment#openDatabase 172 * Environment.openDatabase} method to fail if the database already exists. 173 * 174 * <p>The exclusiveCreate mode is only meaningful if specified with the 175 * allowCreate mode.</p> 176 * 177 * @param exclusiveCreate If true, configure the {@link 178 * com.sleepycat.je.Environment#openDatabase Environment.openDatabase} 179 * method to fail if the database already exists. 180 * 181 * @return this 182 */ setExclusiveCreate(boolean exclusiveCreate)183 public DatabaseConfig setExclusiveCreate(boolean exclusiveCreate) { 184 setExclusiveCreateVoid(exclusiveCreate); 185 return this; 186 } 187 188 /** 189 * @hidden 190 * The void return setter for use by Bean editors. 191 */ setExclusiveCreateVoid(boolean exclusiveCreate)192 public void setExclusiveCreateVoid(boolean exclusiveCreate) { 193 this.exclusiveCreate = exclusiveCreate; 194 } 195 196 /** 197 * Returns true if the {@link com.sleepycat.je.Environment#openDatabase 198 * Environment.openDatabase} method is configured to fail if the database 199 * already exists. 200 * 201 * <p>This method may be called at any time during the life of the 202 * application.</p> 203 * 204 * @return true if the {@link com.sleepycat.je.Environment#openDatabase 205 * Environment.openDatabase} method is configured to fail if the database 206 * already exists. 207 */ getExclusiveCreate()208 public boolean getExclusiveCreate() { 209 return exclusiveCreate; 210 } 211 212 /** 213 * Configures the database to support records with duplicate keys. 214 * 215 * <p>When duplicate keys are configured for a database, key prefixing is 216 * also implicitly configured. Without key prefixing, databases with 217 * duplicates would store keys inefficiently. Key prefixing is therefore 218 * mandatory for databases with duplicates.</p> 219 * 220 * <p>Although two records may have the same key, they may not also have 221 * the same data item. Two identical records, that have the same key and 222 * data, may not be stored in a database.</p> 223 * 224 * <p>The ordering of duplicates in the database is determined by the 225 * duplicate comparison function. See {@link #setDuplicateComparator}. If 226 * the application does not specify a duplicate comparison function, a 227 * default lexical comparison will be used.</p> 228 * 229 * <p>If a primary database is to be associated with one or more secondary 230 * databases, it may not be configured for duplicates.</p> 231 * 232 * <p>Calling this method affects the database, including all threads of 233 * control accessing the database.</p> 234 * 235 * <p>If the database already exists when the database is opened, any 236 * database configuration specified by this method must be the same as the 237 * existing database or an error will be returned.</p> 238 * 239 * @param sortedDuplicates If true, configure the database to support 240 * duplicate data items. A value of false is illegal to this method, that 241 * is, once set, the configuration cannot be cleared. 242 * 243 * @return this 244 */ setSortedDuplicates(boolean sortedDuplicates)245 public DatabaseConfig setSortedDuplicates(boolean sortedDuplicates) { 246 setSortedDuplicatesVoid(sortedDuplicates); 247 return this; 248 } 249 250 /** 251 * @hidden 252 * The void return setter for use by Bean editors. 253 */ setSortedDuplicatesVoid(boolean sortedDuplicates)254 public void setSortedDuplicatesVoid(boolean sortedDuplicates) { 255 this.sortedDuplicates = sortedDuplicates; 256 if (sortedDuplicates) { 257 setKeyPrefixingVoid(true); 258 } 259 } 260 261 /** 262 * Returns true if the database is configured to support records with 263 * duplicate keys. 264 * 265 * <p>This method may be called at any time during the life of the 266 * application.</p> 267 * 268 * @return true if the database is configured to support records with 269 * duplicate keys. 270 */ getSortedDuplicates()271 public boolean getSortedDuplicates() { 272 return sortedDuplicates; 273 } 274 275 /** 276 * Returns the key prefixing configuration. Note that key prefixing is 277 * always enabled for a database with duplicates configured. 278 * 279 * @return true if key prefixing has been enabled in this database. 280 */ getKeyPrefixing()281 public boolean getKeyPrefixing() { 282 return keyPrefixing; 283 } 284 285 /** 286 * Configure the database to support key prefixing. Key prefixing causes 287 * the representation of keys in the b-tree internal nodes to be split 288 * between the common prefix of all keys and the suffixes. Using this 289 * may result in a more space-efficient representation in both the 290 * in-memory and on-disk formats, but at some possible performance cost. 291 * 292 * <p>When duplicate keys are configured for a database, key prefixing is 293 * also implicitly configured. Without key prefixing, databases with 294 * duplicates would store keys inefficiently. Key prefixing is therefore 295 * mandatory for databases with duplicates.</p> 296 * 297 * @param keyPrefixing If true, enables keyPrefixing for the 298 * database. 299 * 300 * @return this 301 * 302 * @throws IllegalStateException if the keyPrefixing argument is false and 303 * {@link #setSortedDuplicates} has been called to configure duplicates. 304 * Key prefixing is therefore mandatory for databases with duplicates. 305 * 306 */ setKeyPrefixing(boolean keyPrefixing)307 public DatabaseConfig setKeyPrefixing(boolean keyPrefixing) { 308 setKeyPrefixingVoid(keyPrefixing); 309 return this; 310 } 311 312 /** 313 * @hidden 314 * The void return setter for use by Bean editors. 315 */ setKeyPrefixingVoid(boolean keyPrefixing)316 public void setKeyPrefixingVoid(boolean keyPrefixing) { 317 if (!keyPrefixing && sortedDuplicates) { 318 throw new IllegalStateException 319 ("Key prefixing is mandatory for databases with duplicates"); 320 } 321 this.keyPrefixing = keyPrefixing; 322 } 323 324 /** 325 * Encloses the database open within a transaction. 326 * 327 * <p>If the call succeeds, the open operation will be recoverable. If the 328 * call fails, no database will have been created.</p> 329 * 330 * <p>All future operations on this database, which are not explicitly 331 * enclosed in a transaction by the application, will be enclosed in in a 332 * transaction within the library.</p> 333 * 334 * @param transactional If true, enclose the database open within a 335 * transaction. 336 * 337 * @return this 338 */ setTransactional(boolean transactional)339 public DatabaseConfig setTransactional(boolean transactional) { 340 setTransactionalVoid(transactional); 341 return this; 342 } 343 344 /** 345 * @hidden 346 * The void return setter for use by Bean editors. 347 */ setTransactionalVoid(boolean transactional)348 public void setTransactionalVoid(boolean transactional) { 349 this.transactional = transactional; 350 } 351 352 /** 353 * Returns true if the database open is enclosed within a transaction. 354 * 355 * <p>This method may be called at any time during the life of the 356 * application.</p> 357 * 358 * @return true if the database open is enclosed within a transaction. 359 */ getTransactional()360 public boolean getTransactional() { 361 return transactional; 362 } 363 364 /** 365 * Configures the database in read-only mode. 366 * 367 * <p>Any attempt to modify items in the database will fail, regardless of 368 * the actual permissions of any underlying files.</p> 369 * 370 * @param readOnly If true, configure the database in read-only mode. 371 * 372 * @return this 373 */ setReadOnly(boolean readOnly)374 public DatabaseConfig setReadOnly(boolean readOnly) { 375 setReadOnlyVoid(readOnly); 376 return this; 377 } 378 379 /** 380 * @hidden 381 * The void return setter for use by Bean editors. 382 */ setReadOnlyVoid(boolean readOnly)383 public void setReadOnlyVoid(boolean readOnly) { 384 this.readOnly = readOnly; 385 } 386 387 /** 388 * Returns true if the database is configured in read-only mode. 389 * 390 * <p>This method may be called at any time during the life of the 391 * application.</p> 392 * 393 * @return true if the database is configured in read-only mode. 394 */ getReadOnly()395 public boolean getReadOnly() { 396 return readOnly; 397 } 398 399 /** 400 * Configures the {@link com.sleepycat.je.Environment#openDatabase 401 * Environment.openDatabase} method to have a B+Tree fanout of 402 * nodeMaxEntries. 403 * 404 * <p>The nodeMaxEntries parameter is only meaningful if specified with the 405 * allowCreate mode. See {@link EnvironmentConfig#NODE_MAX_ENTRIES} for the 406 * valid value range, and the default value. </p> 407 * 408 * @param nodeMaxEntries The maximum children per B+Tree node. 409 * 410 * @return this 411 */ setNodeMaxEntries(int nodeMaxEntries)412 public DatabaseConfig setNodeMaxEntries(int nodeMaxEntries) { 413 setNodeMaxEntriesVoid(nodeMaxEntries); 414 return this; 415 } 416 417 /** 418 * @hidden 419 * The void return setter for use by Bean editors. 420 */ setNodeMaxEntriesVoid(int nodeMaxEntries)421 public void setNodeMaxEntriesVoid(int nodeMaxEntries) { 422 this.nodeMaxEntries = nodeMaxEntries; 423 } 424 425 /** 426 * @deprecated this property no longer has any effect; {@link 427 * #setNodeMaxEntries} should be used instead. 428 */ setNodeMaxDupTreeEntries(int nodeMaxDupTreeEntries)429 public DatabaseConfig setNodeMaxDupTreeEntries(int nodeMaxDupTreeEntries) { 430 return this; 431 } 432 433 /** 434 * @hidden 435 * The void return setter for use by Bean editors. 436 */ setNodeMaxDupTreeEntriesVoid(int nodeMaxDupTreeEntries)437 public void setNodeMaxDupTreeEntriesVoid(int nodeMaxDupTreeEntries) { 438 } 439 440 /** 441 * Returns the maximum number of children a B+Tree node can have. 442 * 443 * <p>This method may be called at any time during the life of the 444 * application.</p> 445 * 446 * @return The maximum number of children a B+Tree node can have. 447 */ getNodeMaxEntries()448 public int getNodeMaxEntries() { 449 return nodeMaxEntries; 450 } 451 452 /** 453 * @deprecated this property no longer has any effect and zero is always 454 * returned; {@link #getNodeMaxEntries} should be used instead. 455 */ getNodeMaxDupTreeEntries()456 public int getNodeMaxDupTreeEntries() { 457 return 0; 458 } 459 460 /** 461 * By default, a byte by byte lexicographic comparison is used for btree 462 * keys. To customize the comparison, supply a different Comparator. 463 * 464 * <p>Note that there are two ways to set the comparator: by specifying the 465 * class or by specifying a serializable object. This method is used to 466 * specify a serializable object. The comparator class must implement 467 * java.util.Comparator and must be serializable. JE will serialize the 468 * Comparator and deserialize it when subsequently opening the 469 * database.</p> 470 * 471 * <p>If a comparator needs to be initialized before it is used or needs 472 * access to the environment's ClassLoader property, it may implement the 473 * {@link DatabaseComparator} interface.</p> 474 * 475 * <p>The Comparator.compare() method is passed the byte arrays that are 476 * stored in the database. If you know how your data is organized in the 477 * byte array, then you can write a comparison routine that directly 478 * examines the contents of the arrays. Otherwise, you have to reconstruct 479 * your original objects, and then perform the comparison. See the <a 480 * href="{@docRoot}/../GettingStartedGuide/comparator.html" 481 * target="_top">Getting Started Guide</a> for examples.</p> 482 * 483 * <p><em>WARNING:</em> There are several special considerations that must 484 * be taken into account when implementing a comparator.<p> 485 * <ul> 486 * <li>Comparator instances are shared by multiple threads and comparator 487 * methods are called without any special synchronization. Therefore, 488 * comparators must be thread safe. In general no shared state should be 489 * used and any caching of computed values must be done with proper 490 * synchronization.</li> 491 * 492 * <li>Because records are stored in the order determined by the 493 * Comparator, the Comparator's behavior must not change over time and 494 * therefore should not be dependent on any state that may change over 495 * time. In addition, although it is possible to change the comparator 496 * for an existing database, care must be taken that the new comparator 497 * provides compatible results with the previous comparator, or database 498 * corruption will occur.</li> 499 * 500 * <li>JE uses comparators internally in a wide variety of circumstances, 501 * so custom comparators must be sure to return valid values for any two 502 * arbitrary keys. The user must not make any assumptions about the 503 * range of key values that might be compared. For example, it's possible 504 * for the comparator may be used against previously deleted values.</li> 505 * </ul> 506 * 507 * <p>A special type of comparator is a <em>partial comparator</em>, which 508 * compares a proper subset (not all bytes) of the key. A partial 509 * comparator allows uniquely identifying a record by a partial key value. 510 * For example, the key could contain multiple fields but could uniquely 511 * identify the record with a single field. The partial comparator could 512 * then compare only the single identifying field. A query ({@link 513 * Cursor#getSearchKey Cursor.getSearchKey}, for example) could then be 514 * performed by passing a partial key that contains only the identifying 515 * field.</p> 516 * 517 * <p><strong>WARNING:</strong> All partial comparators must implement 518 * the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0 519 * or earlier" in the change log and the {@link PartialComparator} javadoc 520 * for more information.</p> 521 * <p> 522 * Another special type of comparator is a <em>binary equality</em> 523 * comparator, which considers two keys to be equal if and only if they 524 * have the same length and they are equal byte-per-byte. All binary 525 * equality comparators must implement the {@link BinaryEqualityComparator} 526 * interface. The significance of binary equality comparators is that they 527 * make possible certain internal optimizations, like the "blind puts" 528 * optimization, described in 529 * {@link BinaryEqualityComparator} 530 * <p> 531 * The comparator for an existing database will not be overridden unless 532 * setOverrideBtreeComparator() is set to true. 533 * 534 * @return this 535 */ setBtreeComparator( Comparator<byte[]> btreeComparator)536 public DatabaseConfig setBtreeComparator( 537 Comparator<byte[]> btreeComparator) { 538 539 setBtreeComparatorVoid(btreeComparator); 540 return this; 541 } 542 543 /** 544 * @hidden 545 * The void return setter for use by Bean editors. 546 */ setBtreeComparatorVoid(Comparator<byte[]> btreeComparator)547 public void setBtreeComparatorVoid(Comparator<byte[]> btreeComparator) { 548 549 /* Note: comparator may be null */ 550 this.btreeComparator = validateComparator(btreeComparator, "Btree"); 551 this.btreeComparatorByClassName = false; 552 } 553 554 /** 555 * By default, a byte by byte lexicographic comparison is used for btree 556 * keys. To customize the comparison, supply a different Comparator. 557 * 558 * <p>Note that there are two ways to set the comparator: by specifying the 559 * class or by specifying a serializable object. This method is used to 560 * specify a Comparator class. The comparator class must implement 561 * java.util.Comparator and must have a public zero-parameter constructor. 562 * JE will store the class name and instantiate the Comparator by class 563 * name (using <code>Class.forName</code> and <code>newInstance</code>) 564 * when subsequently opening the database. Because the Comparator is 565 * instantiated using its default constructor, it should not be dependent 566 * on other constructor parameters.</p> 567 * 568 * <p>The Comparator.compare() method is passed the byte arrays that are 569 * stored in the database. If you know how your data is organized in the 570 * byte array, then you can write a comparison routine that directly 571 * examines the contents of the arrays. Otherwise, you have to reconstruct 572 * your original objects, and then perform the comparison. See the <a 573 * href="{@docRoot}/../GettingStartedGuide/comparator.html" 574 * target="_top">Getting Started Guide</a> for examples.</p> 575 * 576 * <p>If a comparator needs to be initialized before it is used or needs 577 * access to the environment's ClassLoader property, it may implement the 578 * {@link DatabaseComparator} interface.</p> 579 * 580 * <p><em>WARNING:</em> There are several special considerations that must 581 * be taken into account when implementing a comparator.<p> 582 * <ul> 583 * <li>Comparator instances are shared by multiple threads and comparator 584 * methods are called without any special synchronization. Therefore, 585 * comparators must be thread safe. In general no shared state should be 586 * used and any caching of computed values must be done with proper 587 * synchronization.</li> 588 * 589 * <li>Because records are stored in the order determined by the 590 * Comparator, the Comparator's behavior must not change over time and 591 * therefore should not be dependent on any state that may change over 592 * time. In addition, although it is possible to change the comparator 593 * for an existing database, care must be taken that the new comparator 594 * provides compatible results with the previous comparator, or database 595 * corruption will occur.</li> 596 * 597 * <li>JE uses comparators internally in a wide variety of circumstances, 598 * so custom comparators must be sure to return valid values for any two 599 * arbitrary keys. The user must not make any assumptions about the 600 * range of key values that might be compared. For example, it's possible 601 * for the comparator may be used against previously deleted values.</li> 602 * </ul> 603 * 604 * <p>A special type of comparator is a <em>partial comparator</em>, which 605 * compares a proper subset (not all bytes) of the key. A partial 606 * comparator allows uniquely identifying a record by a partial key value. 607 * For example, the key could contain multiple fields but could uniquely 608 * identify the record with a single field. The partial comparator could 609 * then compare only the single identifying field. A query ({@link 610 * Cursor#getSearchKey Cursor.getSearchKey}, for example) could then be 611 * performed by passing a partial key that contains only the identifying 612 * field.</p> 613 * 614 * <p><strong>WARNING:</strong> All partial comparators must implement 615 * the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0 616 * or earlier" in the change log and the {@link PartialComparator} javadoc 617 * for more information.</p> 618 * <p> 619 * Another special type of comparator is a <em>binary equality</em> 620 * comparator, which considers two keys to be equal if and only if they 621 * have the same length and they are equal byte-per-byte. All binary 622 * equality comparators must implement the {@link BinaryEqualityComparator} 623 * interface. The significance of binary equality comparators is that they 624 * make possible certain internal optimizations, like the "blind puts" 625 * optimization, described in 626 * {@link BinaryEqualityComparator} 627 * <p> 628 * The comparator for an existing database will not be overridden unless 629 * setOverrideBtreeComparator() is set to true. 630 * 631 * @return this 632 */ setBtreeComparator( Class<? extends Comparator<byte[]>> btreeComparatorClass)633 public DatabaseConfig setBtreeComparator( 634 Class<? extends Comparator<byte[]>> 635 btreeComparatorClass) { 636 637 setBtreeComparatorVoid(btreeComparatorClass); 638 return this; 639 } 640 641 /** 642 * @hidden 643 * The void return setter for use by Bean editors. 644 */ setBtreeComparatorVoid(Class<? extends Comparator<byte[]>> btreeComparatorClass)645 public void setBtreeComparatorVoid(Class<? extends Comparator<byte[]>> 646 btreeComparatorClass) { 647 648 /* Note: comparator may be null */ 649 this.btreeComparator = validateComparator(btreeComparatorClass, 650 "Btree"); 651 this.btreeComparatorByClassName = true; 652 } 653 654 /** 655 * Returns the Comparator used for key comparison on this database. 656 */ getBtreeComparator()657 public Comparator<byte[]> getBtreeComparator() { 658 return btreeComparator; 659 } 660 661 /** 662 * Returns true if the btree comparator is set by class name, not by 663 * serializable Comparator object 664 * @return true if the comparator is set by class name, not by serializable 665 * Comparator object. 666 */ getBtreeComparatorByClassName()667 public boolean getBtreeComparatorByClassName() { 668 return btreeComparatorByClassName; 669 } 670 671 /** 672 * Sets to true if the database exists and the btree comparator specified 673 * in this configuration object should override the current comparator. 674 * 675 * @param override Set to true to override the existing comparator. 676 * 677 * @return this 678 */ setOverrideBtreeComparator(boolean override)679 public DatabaseConfig setOverrideBtreeComparator(boolean override) { 680 setOverrideBtreeComparatorVoid(override); 681 return this; 682 } 683 684 /** 685 * @hidden 686 * The void return setter for use by Bean editors. 687 */ setOverrideBtreeComparatorVoid(boolean override)688 public void setOverrideBtreeComparatorVoid(boolean override) { 689 overrideBtreeComparator = override; 690 } 691 692 /** 693 * Returns the override setting for the btree comparator. 694 */ getOverrideBtreeComparator()695 public boolean getOverrideBtreeComparator() { 696 return overrideBtreeComparator; 697 } 698 699 /** 700 * By default, a byte by byte lexicographic comparison is used for 701 * duplicate data items in a duplicate set. To customize the comparison, 702 * supply a different Comparator. 703 * 704 * <p>Note that there are two ways to set the comparator: by specifying the 705 * class or by specifying a serializable object. This method is used to 706 * specify a serializable object. The comparator class must implement 707 * java.util.Comparator and must be serializable. JE will serialize the 708 * Comparator and deserialize it when subsequently opening the 709 * database.</p> 710 * 711 * <p>The Comparator.compare() method is passed the byte arrays that are 712 * stored in the database. If you know how your data is organized in the 713 * byte array, then you can write a comparison routine that directly 714 * examines the contents of the arrays. Otherwise, you have to reconstruct 715 * your original objects, and then perform the comparison. See the <a 716 * href="{@docRoot}/../GettingStartedGuide/comparator.html" 717 * target="_top">Getting Started Guide</a> for examples.</p> 718 * 719 * <p>If a comparator needs to be initialized before it is used or needs 720 * access to the environment's ClassLoader property, it may implement the 721 * {@link DatabaseComparator} interface.</p> 722 * 723 * <p><em>WARNING:</em> There are several special considerations that must 724 * be taken into account when implementing a comparator.<p> 725 * <ul> 726 * <li>Comparator instances are shared by multiple threads and comparator 727 * methods are called without any special synchronization. Therefore, 728 * comparators must be thread safe. In general no shared state should be 729 * used and any caching of computed values must be done with proper 730 * synchronization.</li> 731 * 732 * <li>Because records are stored in the order determined by the 733 * Comparator, the Comparator's behavior must not change over time and 734 * therefore should not be dependent on any state that may change over 735 * time. In addition, although it is possible to change the comparator 736 * for an existing database, care must be taken that the new comparator 737 * provides compatible results with the previous comparator, or database 738 * corruption will occur.</li> 739 * 740 * <li>JE uses comparators internally in a wide variety of circumstances, 741 * so custom comparators must be sure to return valid values for any two 742 * arbitrary keys. The user must not make any assumptions about the 743 * range of key values that might be compared. For example, it's possible 744 * for the comparator may be used against previously deleted values.</li> 745 * </ul> 746 * 747 * <p>A special type of comparator is a <em>partial comparator</em>, which 748 * is a comparator that compares a proper subset (not all bytes) of the 749 * data. A partial comparator allows uniquely identifying a record within 750 * a duplicate set by a partial data value. For example, the data could 751 * contain multiple fields but could uniquely identify the record with a 752 * single field. The partial comparator could then compare only the single 753 * identifying field. A query ({@link Cursor#getSearchBoth 754 * Cursor.getSearchBoth}, for example) could then be performed by passing a 755 * partial data value that contains only the identifying field.</p> 756 * 757 * <p>When using a partial comparator, it is possible to update the data 758 * for a duplicate record, as long as only the non-identifying fields in 759 * the data are changed. See {@link Cursor#putCurrent Cursor.putCurrent} 760 * for more information.</p> 761 * 762 * <p><strong>WARNING:</strong> All partial comparators must implement 763 * the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0 764 * or earlier" in the change log and the {@link PartialComparator} javadoc 765 * for more information.</p> 766 * <p> 767 * Another special type of comparator is a <em>binary equality</em> 768 * comparator, which considers two keys to be equal if and only if they 769 * have the same length and they are equal byte-per-byte. All binary 770 * equality comparators must implement the {@link BinaryEqualityComparator} 771 * interface. The significance of binary equality comparators is that they 772 * make possible certain internal optimizations, like the "blind puts" 773 * optimization, described in 774 * {@link BinaryEqualityComparator} 775 * <p> 776 * The comparator for an existing database will not be overridden unless 777 * setOverrideDuplicateComparator() is set to true. 778 */ setDuplicateComparator( Comparator<byte[]> duplicateComparator)779 public DatabaseConfig setDuplicateComparator( 780 Comparator<byte[]> duplicateComparator) { 781 782 /* Note: comparator may be null */ 783 setDuplicateComparatorVoid(duplicateComparator); 784 return this; 785 } 786 787 /** 788 * @hidden 789 * The void return setter for use by Bean editors. 790 */ setDuplicateComparatorVoid( Comparator<byte[]> duplicateComparator)791 public void setDuplicateComparatorVoid( 792 Comparator<byte[]> 793 duplicateComparator) { 794 795 /* Note: comparator may be null */ 796 this.duplicateComparator = 797 validateComparator(duplicateComparator, "Duplicate"); 798 this.duplicateComparatorByClassName = false; 799 } 800 801 /** 802 * By default, a byte by byte lexicographic comparison is used for 803 * duplicate data items in a duplicate set. To customize the comparison, 804 * supply a different Comparator. 805 * 806 * <p>Note that there are two ways to set the comparator: by specifying the 807 * class or by specifying a serializable object. This method is used to 808 * specify a Comparator class. The comparator class must implement 809 * java.util.Comparator and must have a public zero-parameter constructor. 810 * JE will store the class name and instantiate the Comparator by class 811 * name (using <code>Class.forName</code> and <code>newInstance</code>) 812 * when subsequently opening the database. Because the Comparator is 813 * instantiated using its default constructor, it should not be dependent 814 * on other constructor parameters.</p> 815 * 816 * <p>The Comparator.compare() method is passed the byte arrays that are 817 * stored in the database. If you know how your data is organized in the 818 * byte array, then you can write a comparison routine that directly 819 * examines the contents of the arrays. Otherwise, you have to reconstruct 820 * your original objects, and then perform the comparison. See the <a 821 * href="{@docRoot}/../GettingStartedGuide/comparator.html" 822 * target="_top">Getting Started Guide</a> for examples.</p> 823 * 824 * <p>If a comparator needs to be initialized before it is used or needs 825 * access to the environment's ClassLoader property, it may implement the 826 * {@link DatabaseComparator} interface.</p> 827 * 828 * <p><em>WARNING:</em> There are several special considerations that must 829 * be taken into account when implementing a comparator.<p> 830 * <ul> 831 * <li>Comparator instances are shared by multiple threads and comparator 832 * methods are called without any special synchronization. Therefore, 833 * comparators must be thread safe. In general no shared state should be 834 * used and any caching of computed values must be done with proper 835 * synchronization.</li> 836 * 837 * <li>Because records are stored in the order determined by the 838 * Comparator, the Comparator's behavior must not change over time and 839 * therefore should not be dependent on any state that may change over 840 * time. In addition, although it is possible to change the comparator 841 * for an existing database, care must be taken that the new comparator 842 * provides compatible results with the previous comparator, or database 843 * corruption will occur.</li> 844 * 845 * <li>JE uses comparators internally in a wide variety of circumstances, 846 * so custom comparators must be sure to return valid values for any two 847 * arbitrary keys. The user must not make any assumptions about the 848 * range of key values that might be compared. For example, it's possible 849 * for the comparator may be used against previously deleted values.</li> 850 * </ul> 851 * 852 * <p>A special type of comparator is a <em>partial comparator</em>, which 853 * is a comparator that compares a proper subset (not all bytes) of the 854 * data. A partial comparator allows uniquely identifying a record within 855 * a duplicate set by a partial data value. For example, the data could 856 * contain multiple fields but could uniquely identify the record with a 857 * single field. The partial comparator could then compare only the single 858 * identifying field. A query ({@link Cursor#getSearchBoth 859 * Cursor.getSearchBoth}, for example) could then be performed by passing a 860 * partial data value that contains only the identifying field.</p> 861 * 862 * <p>When using a partial comparator, it is possible to update the data 863 * for a duplicate record, as long as only the non-identifying fields in 864 * the data are changed. See {@link Cursor#putCurrent Cursor.putCurrent} 865 * for more information.</p> 866 * 867 * <p><strong>WARNING:</strong> All partial comparators must implement 868 * the {@link PartialComparator} tag interface. See "Upgrading from JE 5.0 869 * or earlier" in the change log and the {@link PartialComparator} javadoc 870 * for more information.</p> 871 * <p> 872 * Another special type of comparator is a <em>binary equality</em> 873 * comparator, which considers two keys to be equal if and only if they 874 * have the same length and they are equal byte-per-byte. All binary 875 * equality comparators must implement the {@link BinaryEqualityComparator} 876 * interface. The significance of binary equality comparators is that they 877 * make possible certain internal optimizations, like the "blind puts" 878 * optimization, described in 879 * {@link BinaryEqualityComparator} 880 * <p> 881 * The comparator for an existing database will not be overridden unless 882 * setOverrideDuplicateComparator() is set to true. 883 * 884 * @return this 885 */ setDuplicateComparator( Class<? extends Comparator<byte[]>> duplicateComparatorClass)886 public DatabaseConfig setDuplicateComparator( 887 Class<? extends Comparator<byte[]>> 888 duplicateComparatorClass) { 889 890 setDuplicateComparatorVoid(duplicateComparatorClass); 891 return this; 892 } 893 894 /** 895 * @hidden 896 * The void return setter for use by Bean editors. 897 */ setDuplicateComparatorVoid( Class<? extends Comparator<byte[]>> duplicateComparatorClass)898 public void setDuplicateComparatorVoid( 899 Class<? extends Comparator<byte[]>> 900 duplicateComparatorClass) { 901 902 /* Note: comparator may be null */ 903 this.duplicateComparator = 904 validateComparator(duplicateComparatorClass, "Duplicate"); 905 this.duplicateComparatorByClassName = true; 906 } 907 908 /** 909 * Returns the Comparator used for duplicate record comparison on this 910 * database. 911 */ getDuplicateComparator()912 public Comparator<byte[]> getDuplicateComparator() { 913 return duplicateComparator; 914 } 915 916 /** 917 * Returns true if the duplicate comparator is set by class name, not by 918 * serializable Comparator object. 919 * 920 * @return true if the duplicate comparator is set by class name, not by 921 * serializable Comparator object. 922 */ getDuplicateComparatorByClassName()923 public boolean getDuplicateComparatorByClassName() { 924 return duplicateComparatorByClassName; 925 } 926 927 /** 928 * Sets to true if the database exists and the duplicate comparator 929 * specified in this configuration object should override the current 930 * comparator. 931 * 932 * @param override Set to true to override the existing comparator. 933 * 934 * @return this 935 */ setOverrideDuplicateComparator(boolean override)936 public DatabaseConfig setOverrideDuplicateComparator(boolean override) { 937 setOverrideDuplicateComparatorVoid(override); 938 return this; 939 } 940 941 /** 942 * @hidden 943 * The void return setter for use by Bean editors. 944 */ setOverrideDuplicateComparatorVoid(boolean override)945 public void setOverrideDuplicateComparatorVoid(boolean override) { 946 overrideDuplicateComparator = override; 947 } 948 949 /** 950 * Returns the override setting for the duplicate comparator. 951 */ getOverrideDuplicateComparator()952 public boolean getOverrideDuplicateComparator() { 953 return overrideDuplicateComparator; 954 } 955 956 /** 957 * @hidden 958 * For internal use only. 959 * 960 * Specifies the list of triggers associated with the database; triggers 961 * are executed in the order specified by this list. 962 * <p> 963 * This configuration parameter is only meaningful when configuring a 964 * <code>Primary</code> database. 965 * <p> 966 * The type of the trigger specified in the list must match the type of 967 * database being configured. For example, the trigger object must 968 * implement the <code>ReplicatedDatabaseTrigger</code> interface if it's 969 * used to configure a replicated database. 970 * <p> 971 * Some of the incorrect uses of this parameter are detected during calls 972 * to {@link Environment#openDatabase Environment.openDatabase} or 973 * {@link Environment#openSecondaryDatabase 974 * Environment.openSecondaryDatabase} and will result in an 975 * <code>IllegalArgumentException</code>. 976 * 977 * @param triggers the list of database triggers to be associated with the 978 * environment. 979 * 980 * @throws IllegalArgumentException If the triggers in the list do not have 981 * unique names, have conflicting types (e.g. only a subset implement 982 * {@link ReplicatedDatabaseTrigger ReplicatedDatabaseTrigger}), or do not 983 * implement {@link ReplicatedDatabaseTrigger ReplicatedDatabaseTrigger} 984 * for a replicated database. 985 * 986 * @return this 987 */ setTriggers(List<Trigger> triggers)988 public DatabaseConfig setTriggers(List<Trigger> triggers) { 989 setTriggersVoid(triggers); 990 return this; 991 } 992 993 /** 994 * @hidden 995 * The void return setter for use by Bean editors. 996 */ setTriggersVoid(List<Trigger> triggers)997 public void setTriggersVoid(List<Trigger> triggers) { 998 this.triggers = triggers; 999 1000 if ((triggers == null) || (triggers.size() == 0)) { 1001 return; 1002 } 1003 1004 checkTriggers(triggers); 1005 } 1006 1007 /** 1008 * @hidden 1009 * For internal use only. 1010 * 1011 * Returns the list of configured database triggers. 1012 */ getTriggers()1013 public List<Trigger> getTriggers() { 1014 return triggers; 1015 } 1016 1017 /** 1018 * @hidden 1019 * For internal use only. 1020 * 1021 * Set to true if the database exists and the {@link PersistentTrigger}s in 1022 * the trigger list specified in this configuration object should override 1023 * those in the current list of triggers. Note that any transient triggers 1024 * that are specified are always configured, because they do not override 1025 * existing triggers. 1026 * 1027 * @param override Set to true to override the existing comparator. 1028 * 1029 * @return this 1030 */ setOverrideTriggers(boolean override)1031 public DatabaseConfig setOverrideTriggers(boolean override) { 1032 setOverrideTriggersVoid(override); 1033 return this; 1034 } 1035 1036 /** 1037 * @hidden 1038 * The void return setter for use by Bean editors. 1039 */ setOverrideTriggersVoid(boolean override)1040 public void setOverrideTriggersVoid(boolean override) { 1041 overrideTriggers = override; 1042 } 1043 1044 /** 1045 * @hidden 1046 * For internal use only. 1047 * 1048 * Returns the override setting for triggers. 1049 */ getOverrideTriggers()1050 public boolean getOverrideTriggers() { 1051 return overrideTriggers; 1052 } 1053 1054 /** 1055 * Sets the temporary database option. 1056 * 1057 * <p> Temporary databases operate internally in deferred-write mode to 1058 * provide reduced disk I/O and increased concurrency. But unlike an 1059 * ordinary deferred-write database, the information in a temporary 1060 * database is not durable or persistent. 1061 * 1062 * <p> A temporary database is not flushed to disk when the database is 1063 * closed or when a checkpoint is performed, and the Database.sync method 1064 * may not be called. When all handles for a temporary database are 1065 * closed, the database is automatically removed. If a crash occurs before 1066 * closing a temporary database, the database will be automatically removed 1067 * when the environment is re-opened. 1068 * 1069 * <p> Note that although temporary databases can page to disk if the cache 1070 * is not large enough to hold the databases, they are much more efficient 1071 * if the database remains in memory. See the JE FAQ on the Oracle 1072 * Technology Network site for information on how to estimate the cache 1073 * size needed by a given database. 1074 * 1075 * <p> 1076 * See the {@link <a 1077 * href="{@docRoot}/../GettingStartedGuide/DB.html#tempdbje">Getting 1078 * Started Guide, Database chapter</a>} for a full description of temporary 1079 * databases. 1080 * <p> 1081 * @param temporary if true, the database will be opened as a temporary 1082 * database. 1083 * 1084 * @return this 1085 */ setTemporary(boolean temporary)1086 public DatabaseConfig setTemporary(boolean temporary) { 1087 setTemporaryVoid(temporary); 1088 return this; 1089 } 1090 1091 /** 1092 * @hidden 1093 * The void return setter for use by Bean editors. 1094 */ setTemporaryVoid(boolean temporary)1095 public void setTemporaryVoid(boolean temporary) { 1096 this.temporary = temporary; 1097 } 1098 1099 /** 1100 * Returns the temporary database option. 1101 * @return boolean if true, the database is temporary. 1102 */ getTemporary()1103 public boolean getTemporary() { 1104 return temporary; 1105 } 1106 1107 /** 1108 * Sets the deferred-write option. 1109 * 1110 * <p> Deferred-write databases have reduced disk I/O and improved 1111 * concurrency. Disk I/O is reduced when data records are frequently 1112 * modified or deleted. The information in a deferred-write database is 1113 * not guaranteed to be durable or persistent until {@link Database#close} 1114 * or {@link Database#sync} is called, or a checkpoint is performed. Since 1115 * the usual write ahead logging system is relaxed in order to improve 1116 * performance, if the environment crashes before a {@link Database#sync} 1117 * or {@link Database#close}, none, all, or a unpredictable set of the 1118 * operations previously done may be persistent. 1119 * 1120 * <p> After a deferred-write database is closed it may be re-opened as an 1121 * ordinary transactional or non-transactional database. For example, this 1122 * can be used to initially load a large data set in deferred-write mode 1123 * and then switch to transactional mode for subsequent operations. 1124 * 1125 * <p> Note that although deferred-write databases can page to disk if the 1126 * cache is not large enough to hold the databases, they are much more 1127 * efficient if the database remains in memory. See the JE FAQ on the 1128 * Oracle Technology Network site for information on how to estimate the 1129 * cache size needed by a given database. 1130 * 1131 * <p> 1132 * See the {@link <a 1133 * href="{@docRoot}/../GettingStartedGuide/DB.html#dwdatabase">Getting 1134 * Started Guide, Database chapter</a>} for a full description 1135 * of deferred-write databases. 1136 * 1137 * <p> 1138 * @param deferredWrite if true, the database will be opened as a 1139 * deferred-write database. 1140 * 1141 * @return this 1142 */ setDeferredWrite(boolean deferredWrite)1143 public DatabaseConfig setDeferredWrite(boolean deferredWrite) { 1144 setDeferredWriteVoid(deferredWrite); 1145 return this; 1146 } 1147 1148 /** 1149 * @hidden 1150 * The void return setter for use by Bean editors. 1151 */ setDeferredWriteVoid(boolean deferredWrite)1152 public void setDeferredWriteVoid(boolean deferredWrite) { 1153 this.deferredWrite = deferredWrite; 1154 } 1155 1156 /** 1157 * Returns the deferred-write option. 1158 * 1159 * @return boolean if true, deferred-write is enabled. 1160 */ getDeferredWrite()1161 public boolean getDeferredWrite() { 1162 return deferredWrite; 1163 } 1164 1165 /** 1166 * Used to set the comparator when filling in a configuration from an 1167 * existing database. 1168 */ setBtreeComparatorInternal(Comparator<byte[]> comparator, boolean byClassName)1169 void setBtreeComparatorInternal(Comparator<byte[]> comparator, 1170 boolean byClassName) { 1171 btreeComparator = comparator; 1172 btreeComparatorByClassName = byClassName; 1173 } 1174 1175 /** 1176 * Used to set the comparator when filling in a configuration from an 1177 * existing database. 1178 */ setDuplicateComparatorInternal(Comparator<byte[]> comparator, boolean byClassName)1179 void setDuplicateComparatorInternal(Comparator<byte[]> comparator, 1180 boolean byClassName) { 1181 duplicateComparator = comparator; 1182 duplicateComparatorByClassName = byClassName; 1183 } 1184 1185 /** 1186 * Setting useExistingConfig to true allows a program to open a database 1187 * without knowing a prior what its configuration is. For example, if you 1188 * want to open a database without knowing whether it contains sorted 1189 * duplicates or not, you can set this property to true. In general, this 1190 * is used by the JE utilities, to avoid having to know the configuration 1191 * of a database. The databases should be opened readOnly when this 1192 * property is set to true. 1193 * 1194 * @param useExistingConfig true if this Database should be opened using 1195 * the existing configuration. 1196 * 1197 * @return this 1198 */ setUseExistingConfig(boolean useExistingConfig)1199 public DatabaseConfig setUseExistingConfig(boolean useExistingConfig) { 1200 setUseExistingConfigVoid(useExistingConfig); 1201 return this; 1202 } 1203 1204 /** 1205 * @hidden 1206 * The void return setter for use by Bean editors. 1207 */ setUseExistingConfigVoid(boolean useExistingConfig)1208 public void setUseExistingConfigVoid(boolean useExistingConfig) { 1209 this.useExistingConfig = useExistingConfig; 1210 } 1211 1212 /** 1213 * Return the value of the useExistingConfig property. 1214 * 1215 * @return the value of the useExistingConfig property. 1216 */ getUseExistingConfig()1217 public boolean getUseExistingConfig() { 1218 return useExistingConfig; 1219 } 1220 1221 /** 1222 * Sets the default {@code CacheMode} used for operations performed on this 1223 * database. If this property is non-null, it overrides the default 1224 * specified using {@link EnvironmentConfig#setCacheMode} for operations on 1225 * this database. The default cache mode may be overridden on a per-record 1226 * or per-operation basis using {@link Cursor#setCacheMode}. 1227 * 1228 * @param cacheMode is the default {@code CacheMode} used for operations 1229 * performed on this database. If {@code null} is specified, the 1230 * environment default will be used. 1231 * 1232 * @see CacheMode for further details. 1233 * 1234 * @since 4.0.97 1235 */ setCacheMode(final CacheMode cacheMode)1236 public DatabaseConfig setCacheMode(final CacheMode cacheMode) { 1237 setCacheModeVoid(cacheMode); 1238 return this; 1239 } 1240 1241 /** 1242 * @hidden 1243 * The void return setter for use by Bean editors. 1244 */ setCacheModeVoid(final CacheMode cacheMode)1245 public void setCacheModeVoid(final CacheMode cacheMode) { 1246 this.cacheMode = cacheMode; 1247 } 1248 1249 /** 1250 * Returns the default {@code CacheMode} used for operations performed on 1251 * this database, or null if the environment default is used. 1252 * 1253 * @return the default {@code CacheMode} used for operations performed on 1254 * this database, or null if the environment default is used. 1255 * 1256 * @see #setCacheMode 1257 * 1258 * @since 4.0.97 1259 */ getCacheMode()1260 public CacheMode getCacheMode() { 1261 return cacheMode; 1262 } 1263 1264 /** 1265 * @hidden 1266 * For internal use only. 1267 * 1268 * Sets the {@code CacheModeStrategy} used for operations performed on this 1269 * database. If this property is non-null, it overrides the default 1270 * specified using {@link EnvironmentConfig#setCacheModeStrategy} for 1271 * operations on this database. 1272 * 1273 * @param strategy is the {@code CacheModeStrategy} used for operations 1274 * performed on this database. If {@code null} is specified, the 1275 * environment default will be used. 1276 * 1277 * @see CacheModeStrategy for further details. 1278 * 1279 * @since 4.0.97 1280 */ setCacheModeStrategy( final CacheModeStrategy strategy)1281 public DatabaseConfig setCacheModeStrategy( 1282 final CacheModeStrategy strategy) { 1283 cacheModeStrategy = strategy; 1284 return this; 1285 } 1286 1287 /** 1288 * @hidden 1289 * The void return setter for use by Bean editors. 1290 */ setCacheModeStrategyVoid(final CacheModeStrategy strategy)1291 public void setCacheModeStrategyVoid(final CacheModeStrategy strategy) { 1292 cacheModeStrategy = strategy; 1293 } 1294 1295 /** 1296 * @hidden 1297 * For internal use only. 1298 * 1299 * Returns the {@code CacheModeStrategy} used for operations performed on 1300 * this database, or null if the environment default is used. 1301 * 1302 * @return the default {@code CacheModeStrategy} used for operations 1303 * performed on this database, or null if the environment default is used. 1304 * 1305 * @see #setCacheModeStrategy 1306 * 1307 * @since 4.0.97 1308 */ getCacheModeStrategy()1309 public CacheModeStrategy getCacheModeStrategy() { 1310 return cacheModeStrategy; 1311 } 1312 1313 /** 1314 * Configures a database to be replicated or non-replicated, in a 1315 * replicated Environment. By default this property is true, meaning that 1316 * by default a database is replicated in a replicated Environment. 1317 * <p> 1318 * In a non-replicated Environment, this property is ignored. All 1319 * databases are non-replicated in a non-replicated Environment. 1320 * 1321 * @see 1322 * <a href="rep/ReplicatedEnvironment.html#nonRepDbs">Non-replicated 1323 * Databases in a Replicated Environment</a> 1324 */ setReplicated(boolean replicated)1325 public DatabaseConfig setReplicated(boolean replicated) { 1326 setReplicatedVoid(replicated); 1327 return this; 1328 } 1329 1330 /** 1331 * @hidden 1332 * The void return setter for use by Bean editors. 1333 */ setReplicatedVoid(boolean replicated)1334 public void setReplicatedVoid(boolean replicated) { 1335 this.replicated = replicated; 1336 } 1337 1338 /** 1339 * Returns the replicated property for the database. 1340 * <p> 1341 * This method returns true by default. However, in a non-replicated 1342 * Environment, this property is ignored. All databases are non-replicated 1343 * in a non-replicated Environment. 1344 * 1345 * @see #setReplicated 1346 */ getReplicated()1347 public boolean getReplicated() { 1348 return replicated; 1349 } 1350 1351 /** 1352 * @hidden 1353 * For internal use only. 1354 * 1355 * Configures a SecondaryAssociation that is used to define 1356 * primary-secondary associations for a group of primary and secondary 1357 * databases. The same SecondaryAssociation instance must be configured on 1358 * the primary and secondary databases. 1359 * 1360 * @see SecondaryAssociation 1361 */ 1362 public DatabaseConfig setSecondaryAssociation(SecondaryAssociation association)1363 setSecondaryAssociation(SecondaryAssociation association) { 1364 setSecondaryAssociationVoid(association); 1365 return this; 1366 } 1367 1368 /** 1369 * @hidden 1370 * The void return setter for use by Bean editors. 1371 */ setSecondaryAssociationVoid(SecondaryAssociation association)1372 public void setSecondaryAssociationVoid(SecondaryAssociation association) { 1373 secAssociation = association; 1374 } 1375 1376 /** 1377 * @hidden 1378 * For internal use only. 1379 * 1380 * Returns the configured SecondaryAssociation. 1381 * 1382 * @see #setSecondaryAssociation 1383 * @see SecondaryAssociation 1384 */ getSecondaryAssociation()1385 public SecondaryAssociation getSecondaryAssociation() { 1386 return secAssociation; 1387 } 1388 1389 /** 1390 * Returns a copy of this configuration object. 1391 * 1392 * @deprecated As of JE 4.0.13, replaced by {@link 1393 * DatabaseConfig#clone()}.</p> 1394 */ cloneConfig()1395 public DatabaseConfig cloneConfig() { 1396 return clone(); 1397 } 1398 1399 /** 1400 * Returns a copy of this configuration object. 1401 */ 1402 @Override clone()1403 public DatabaseConfig clone() { 1404 try { 1405 return (DatabaseConfig) super.clone(); 1406 } catch (CloneNotSupportedException willNeverOccur) { 1407 return null; 1408 } 1409 } 1410 1411 /** 1412 * For JCA Database handle caching. 1413 * 1414 * @throws IllegalArgumentException via JEConnection.openDatabase. 1415 */ validate(DatabaseConfig config)1416 void validate(DatabaseConfig config) 1417 throws DatabaseException { 1418 1419 if (config == null) { 1420 config = DatabaseConfig.DEFAULT; 1421 } 1422 1423 boolean txnMatch = (config.transactional == transactional); 1424 boolean roMatch = (config.readOnly == readOnly); 1425 boolean sdMatch = (config.sortedDuplicates == sortedDuplicates); 1426 boolean dwMatch = (config.getDeferredWrite() == deferredWrite); 1427 boolean btCmpMatch = true; 1428 if (config.overrideBtreeComparator) { 1429 if (btreeComparator == null) { 1430 btCmpMatch = (config.btreeComparator == null); 1431 } else if (config.btreeComparatorByClassName != 1432 btreeComparatorByClassName) { 1433 btCmpMatch = false; 1434 } else if (btreeComparatorByClassName) { 1435 btCmpMatch = btreeComparator.getClass() == 1436 config.btreeComparator.getClass(); 1437 } else { 1438 btCmpMatch = Arrays.equals 1439 (DatabaseImpl.objectToBytes 1440 (btreeComparator, "Btree"), 1441 DatabaseImpl.objectToBytes 1442 (config.btreeComparator, "Btree")); 1443 } 1444 } 1445 boolean dtCmpMatch = true; 1446 if (config.overrideDuplicateComparator) { 1447 if (duplicateComparator == null) { 1448 dtCmpMatch = (config.duplicateComparator == null); 1449 } else if (config.duplicateComparatorByClassName != 1450 duplicateComparatorByClassName) { 1451 dtCmpMatch = false; 1452 } else if (duplicateComparatorByClassName) { 1453 dtCmpMatch = duplicateComparator.getClass() == 1454 config.duplicateComparator.getClass(); 1455 } else { 1456 dtCmpMatch = Arrays.equals 1457 (DatabaseImpl.objectToBytes 1458 (duplicateComparator, "Duplicate"), 1459 DatabaseImpl.objectToBytes 1460 (config.duplicateComparator, "Duplicate")); 1461 } 1462 } 1463 1464 if (txnMatch && 1465 roMatch && 1466 sdMatch && 1467 dwMatch && 1468 btCmpMatch && 1469 dtCmpMatch) { 1470 return; 1471 } 1472 String message = genDatabaseConfigMismatchMessage 1473 (txnMatch, roMatch, sdMatch, dwMatch, 1474 btCmpMatch, dtCmpMatch); 1475 throw new IllegalArgumentException(message); 1476 } 1477 genDatabaseConfigMismatchMessage(boolean txnMatch, boolean roMatch, boolean sdMatch, boolean dwMatch, boolean btCmpMatch, boolean dtCmpMatch)1478 private String genDatabaseConfigMismatchMessage(boolean txnMatch, 1479 boolean roMatch, 1480 boolean sdMatch, 1481 boolean dwMatch, 1482 boolean btCmpMatch, 1483 boolean dtCmpMatch) { 1484 StringBuilder ret = new StringBuilder 1485 ("The following DatabaseConfig parameters for the\n" + 1486 "cached Database do not match the parameters for the\n" + 1487 "requested Database:\n"); 1488 if (!txnMatch) { 1489 ret.append(" Transactional\n"); 1490 } 1491 1492 if (!roMatch) { 1493 ret.append(" Read-Only\n"); 1494 } 1495 1496 if (!sdMatch) { 1497 ret.append(" Sorted Duplicates\n"); 1498 } 1499 1500 if (!dwMatch) { 1501 ret.append(" Deferred Write"); 1502 } 1503 1504 if (!btCmpMatch) { 1505 ret.append(" Btree Comparator\n"); 1506 } 1507 1508 if (!dtCmpMatch) { 1509 ret.append(" Duplicate Comparator\n"); 1510 } 1511 1512 return ret.toString(); 1513 } 1514 1515 /** 1516 * Checks that this comparator can be serialized by JE. 1517 * 1518 * @throws IllegalArgumentException via setBtreeComparator and 1519 * setDuplicateComparator 1520 */ validateComparator( Comparator<byte[]> comparator, String type)1521 private Comparator<byte[]> validateComparator( 1522 Comparator<byte[]> comparator, 1523 String type) 1524 throws IllegalArgumentException { 1525 1526 if (comparator == null) { 1527 return null; 1528 } 1529 1530 try { 1531 DatabaseImpl.comparatorToBytes(comparator, false /*byClassName*/, 1532 type); 1533 return comparator; 1534 } catch (DatabaseException e) { 1535 throw new IllegalArgumentException 1536 (type + " comparator is not valid.", e); 1537 } 1538 } 1539 1540 /** 1541 * Checks that this comparator class can be instantiated by JE. 1542 * 1543 * @throws IllegalArgumentException via setBtreeComparator and 1544 * setDuplicateComparator 1545 */ validateComparator( Class<? extends Comparator<byte[]>> comparatorClass, String type)1546 private Comparator<byte[]> validateComparator( 1547 Class<? extends Comparator<byte[]>> comparatorClass, 1548 String type) 1549 throws IllegalArgumentException { 1550 1551 if (comparatorClass == null) { 1552 return null; 1553 } 1554 1555 if (!Comparator.class.isAssignableFrom(comparatorClass)) { 1556 throw new IllegalArgumentException 1557 (comparatorClass.getName() + 1558 " is is not valid as a " + type + 1559 " comparator because it does not " + 1560 " implement java.util.Comparator."); 1561 } 1562 1563 try { 1564 return DatabaseImpl.instantiateComparator(comparatorClass, type); 1565 } catch (DatabaseException e) { 1566 throw new IllegalArgumentException 1567 (type + " comparator is not valid. " + 1568 "Perhaps you have not implemented a zero-parameter " + 1569 "constructor for the comparator or the comparator class " + 1570 "cannot be found.", 1571 e); 1572 } 1573 } 1574 1575 /** 1576 * Checks that this database configuration is valid for a new, non-existant 1577 * database. 1578 * 1579 * @throws IllegalArgumentException via Environment.openDatabase and 1580 * openSecondaryDatabase 1581 */ validateForNewDb()1582 void validateForNewDb() 1583 throws DatabaseException { 1584 1585 if (readOnly) { 1586 throw new IllegalArgumentException 1587 ("DatabaseConfig.setReadOnly() must be set to false " + 1588 "when creating a Database"); 1589 } 1590 1591 if (transactional && deferredWrite) { 1592 throw new IllegalArgumentException 1593 ("deferredWrite mode is not supported for transactional " + 1594 "databases"); 1595 } 1596 } 1597 1598 /** 1599 * For unit tests, checks that the database configuration attributes that 1600 * are saved persistently are equal. 1601 */ persistentEquals(DatabaseConfig other)1602 boolean persistentEquals(DatabaseConfig other) { 1603 if (sortedDuplicates != other.sortedDuplicates) { 1604 return false; 1605 } 1606 1607 if (temporary != other.temporary) { 1608 return false; 1609 } 1610 1611 if (replicated != other.replicated) { 1612 return false; 1613 } 1614 1615 if (nodeMaxEntries != other.nodeMaxEntries) { 1616 return false; 1617 } 1618 1619 if (((btreeComparator == null) && (other.btreeComparator != null)) || 1620 ((btreeComparator != null) && (other.btreeComparator == null))) { 1621 return false; 1622 } 1623 1624 if (btreeComparator != null) { 1625 if (btreeComparator.getClass() != 1626 other.btreeComparator.getClass()) { 1627 return false; 1628 } 1629 } 1630 1631 if (((duplicateComparator == null) && 1632 (other.duplicateComparator != null)) || 1633 ((duplicateComparator != null) && 1634 (other.duplicateComparator == null))) { 1635 return false; 1636 } 1637 1638 if ((duplicateComparator != null)) { 1639 if (duplicateComparator.getClass() != 1640 other.duplicateComparator.getClass()) { 1641 return false; 1642 } 1643 } 1644 1645 return true; 1646 } 1647 1648 /** 1649 * Perform validations at database open time on the completed DbConfig 1650 * object. Inter-attribute checks are done here. 1651 */ validateOnDbOpen(String databaseName, boolean dbIsReplicated)1652 void validateOnDbOpen(String databaseName, 1653 boolean dbIsReplicated) { 1654 1655 if ((getDeferredWrite() && getTemporary()) || 1656 (getDeferredWrite() && getTransactional()) || 1657 (getTemporary() && getTransactional())) { 1658 throw new IllegalArgumentException 1659 ("Attempted to open Database " + databaseName + 1660 " and two ore more of the following exclusive properties" + 1661 " are true: deferredWrite, temporary, transactional"); 1662 } 1663 1664 if ((triggers != null) && (triggers.size() > 0)) { 1665 1666 final boolean replicatedTriggers = checkTriggers(triggers); 1667 if (dbIsReplicated && !replicatedTriggers) { 1668 throw new IllegalArgumentException 1669 ("For a replicated Database, triggers must implement " + 1670 ReplicatedDatabaseTrigger.class.getName()); 1671 } 1672 } 1673 } 1674 1675 /** 1676 * Checks that the triggers in the list have consistent definitions. 1677 * 1678 * @param triggerList the list of triggers to be checked 1679 * 1680 * @return true if the list consists of just replicated triggers, false if 1681 * it consists entirely of non-replicated triggers. 1682 * 1683 * @throws IllegalArgumentException if the list had triggers with duplicate 1684 * names or the types were not consistent. 1685 */ checkTriggers(List<Trigger> triggerList)1686 boolean checkTriggers(List<Trigger> triggerList) { 1687 1688 final boolean replicatedTrigger = 1689 triggerList.get(0) instanceof ReplicatedDatabaseTrigger; 1690 1691 final Set<String> triggerNames = new HashSet<String>(); 1692 1693 for (Trigger trigger : triggerList) { 1694 1695 /* 1696 * Note that we do not disallow the unsupported PersistentTrigger 1697 * or ReplicatedDatabaseTrigger intefaces here, to enable the 1698 * continued testing of these partially implemented features. 1699 * 1700 if (trigger instanceof PersistentTrigger) { 1701 throw new IllegalArgumentException 1702 ("PeristentTrigger not supported: " + trigger.getName()); 1703 } 1704 */ 1705 1706 if (!triggerNames.add(trigger.getName())) { 1707 throw new IllegalArgumentException 1708 ("Duplicate trigger name:" + trigger.getName()); 1709 } 1710 if (replicatedTrigger != 1711 (trigger instanceof ReplicatedDatabaseTrigger)) { 1712 throw new IllegalArgumentException 1713 ("Conflicting trigger types in list:" + triggerList); 1714 } 1715 } 1716 return replicatedTrigger; 1717 } 1718 1719 /** 1720 * Combine the per-Database handle and Database-wide properties for a 1721 * database handle. 1722 * 1723 * @param dbImpl the underlying DatabaseImpl for a database handle, which 1724 * provides the Database-wide properties 1725 * 1726 * @param dbHandleConfig DatabaseConfig field for the same database handle, 1727 * which provides the per-Database properties. 1728 * 1729 * @return a DatabaseConfig which includes the correct Database-wide and 1730 * per-Database handle properties. 1731 */ combineConfig(DatabaseImpl dbImpl, DatabaseConfig dbHandleConfig)1732 static DatabaseConfig combineConfig(DatabaseImpl dbImpl, 1733 DatabaseConfig dbHandleConfig) { 1734 1735 DatabaseConfig showConfig = dbHandleConfig.cloneConfig(); 1736 1737 /* 1738 * Set the Database-wide properties from the DatabaseImpl, since they 1739 * might have changed from other database handles. 1740 * 1741 * Note: sorted duplicates, temporary and replicated attributes are not 1742 * mutable and were checked at handle creation to make sure these 1743 * properties in dbHandleConfig are consistent with 1744 * DatabaseImpl. They're still set here in case the useExistingConfig 1745 * property is set, and those field were not initialized. 1746 */ 1747 if (dbImpl != null) { 1748 /* mutable, persistent, database wide attributes. */ 1749 showConfig.setBtreeComparatorInternal 1750 (dbImpl.getBtreeComparator(), 1751 dbImpl.getBtreeComparatorByClass()); 1752 showConfig.setDuplicateComparatorInternal 1753 (dbImpl.getDuplicateComparator(), 1754 dbImpl.getDuplicateComparatorByClass()); 1755 showConfig.setKeyPrefixing(dbImpl.getKeyPrefixing()); 1756 showConfig.setNodeMaxEntries(dbImpl.getNodeMaxTreeEntries()); 1757 showConfig.setTriggers(dbImpl.getTriggers()); 1758 1759 /* mutable, but non-persistent attributes. */ 1760 showConfig.setTransactional(dbImpl.isTransactional()); 1761 showConfig.setDeferredWrite(dbImpl.isDurableDeferredWrite()); 1762 1763 /* not mutable, but initialized in the showConfig. */ 1764 showConfig.setReplicated(dbImpl.isReplicated()); 1765 showConfig.setSortedDuplicates(dbImpl.getSortedDuplicates()); 1766 showConfig.setTemporary(dbImpl.isTemporary()); 1767 } 1768 1769 return showConfig; 1770 } 1771 1772 /** 1773 * Returns the values for each configuration attribute. 1774 * 1775 * @return the values for each configuration attribute. 1776 */ 1777 @Override toString()1778 public String toString() { 1779 return "allowCreate=" + allowCreate + 1780 "\nexclusiveCreate=" + exclusiveCreate + 1781 "\ntransactional=" + transactional + 1782 "\nreadOnly=" + readOnly + 1783 "\nsortedDuplicates=" + sortedDuplicates + 1784 "\ndeferredWrite=" + deferredWrite + 1785 "\ntemporary=" + temporary + 1786 "\nkeyPrefixing=" + keyPrefixing + 1787 "\n"; 1788 } 1789 } 1790