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.io.File; 11 import java.util.Properties; 12 13 import com.sleepycat.je.dbi.CursorImpl; 14 import com.sleepycat.je.dbi.CursorImpl.SearchMode; 15 import com.sleepycat.je.dbi.DatabaseImpl; 16 import com.sleepycat.je.dbi.DiskOrderedCursorImpl; 17 import com.sleepycat.je.dbi.EnvironmentImpl; 18 import com.sleepycat.je.dbi.GetMode; 19 import com.sleepycat.je.dbi.PutMode; 20 import com.sleepycat.je.log.ReplicationContext; 21 import com.sleepycat.je.tree.LN; 22 import com.sleepycat.je.txn.Locker; 23 import com.sleepycat.je.txn.Txn; 24 import com.sleepycat.util.keyrange.KeyRange; 25 import com.sleepycat.util.keyrange.RangeCursor; 26 27 /** 28 * @hidden 29 * For internal use only. It serves to shelter methods that must be public to 30 * be used by other BDB JE packages but that are not part of the public API 31 * available to applications. 32 */ 33 public class DbInternal { 34 35 /** 36 * Proxy to Database.invalidate() 37 */ invalidate(final Database db)38 public static void invalidate(final Database db) { 39 db.invalidate(); 40 } 41 42 /** 43 * Proxy to Database.setPreempted() 44 */ setPreempted(final Database db, final String dbName, final String msg)45 public static void setPreempted(final Database db, 46 final String dbName, 47 final String msg) { 48 db.setPreempted(dbName, msg); 49 } 50 51 /** 52 * Proxy to Environment.getEnvironmentImpl 53 */ getEnvironmentImpl(final Environment env)54 public static EnvironmentImpl getEnvironmentImpl(final Environment env) { 55 return env.getEnvironmentImpl(); 56 } 57 58 /** 59 * Proxy to Environment.closeInternalHandle 60 */ closeInternalHandle(final Environment env)61 public static void closeInternalHandle(final Environment env) { 62 env.closeInternalHandle(); 63 } 64 65 /** 66 * Proxy to Cursor.position(). 67 */ position( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data, final LockMode lockMode, final boolean first)68 public static OperationStatus position( 69 final Cursor cursor, 70 final DatabaseEntry key, 71 final DatabaseEntry data, 72 final LockMode lockMode, 73 final boolean first) { 74 75 return cursor.position(key, data, lockMode, first); 76 } 77 78 /** 79 * Proxy to Cursor.search(). 80 */ search( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data, final LockMode lockMode, final SearchMode searchMode)81 public static OperationStatus search( 82 final Cursor cursor, 83 final DatabaseEntry key, 84 final DatabaseEntry data, 85 final LockMode lockMode, 86 final SearchMode searchMode) { 87 88 return cursor.search(key, data, lockMode, searchMode); 89 } 90 91 /** 92 * Proxy to Cursor.searchForReplay(). 93 */ searchForReplay( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data, final LockMode lockMode, final SearchMode searchMode)94 public static OperationStatus searchForReplay( 95 final Cursor cursor, 96 final DatabaseEntry key, 97 final DatabaseEntry data, 98 final LockMode lockMode, 99 final SearchMode searchMode) { 100 101 return cursor.searchForReplay(key, data, lockMode, searchMode); 102 } 103 104 /** 105 * Proxy to Cursor.retrieveNext(). 106 */ retrieveNext( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data, final LockMode lockMode, final GetMode getMode)107 public static OperationStatus retrieveNext( 108 final Cursor cursor, 109 final DatabaseEntry key, 110 final DatabaseEntry data, 111 final LockMode lockMode, 112 final GetMode getMode) 113 throws DatabaseException { 114 115 return cursor.retrieveNext(key, data, lockMode, getMode); 116 } 117 118 /** 119 * Proxy to Cursor.advanceCursor() 120 */ advanceCursor( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data)121 public static boolean advanceCursor( 122 final Cursor cursor, 123 final DatabaseEntry key, 124 final DatabaseEntry data) { 125 126 return cursor.advanceCursor(key, data); 127 } 128 129 /** 130 * Proxy to Cursor.deleteInternal() 131 */ deleteInternal( final Cursor cursor, final ReplicationContext repContext)132 public static OperationStatus deleteInternal( 133 final Cursor cursor, 134 final ReplicationContext repContext) { 135 136 return cursor.deleteInternal(repContext); 137 } 138 139 /** 140 * Proxy to Cursor.putForReplay() 141 */ putForReplay( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry data, final LN ln, final PutMode putMode, final ReplicationContext repContext)142 public static OperationStatus putForReplay( 143 final Cursor cursor, 144 final DatabaseEntry key, 145 final DatabaseEntry data, 146 final LN ln, 147 final PutMode putMode, 148 final ReplicationContext repContext) { 149 150 return cursor.putForReplay(key, data, ln, putMode, repContext); 151 } 152 153 /** 154 * Search mode used with the internal search and searchBoth methods. 155 */ 156 public enum Search { 157 158 /** 159 * Match the smallest value greater than the key or data param. 160 */ 161 GT, 162 163 /** 164 * Match the smallest value greater than or equal to the key or data 165 * param. 166 */ 167 GTE, 168 169 /** 170 * Match the largest value less than the key or data param. 171 */ 172 LT, 173 174 /** 175 * Match the largest value less than or equal to the key or data param. 176 */ 177 LTE, 178 } 179 180 /** 181 * Finds the key according to the Search param. If dups are configured, GT 182 * and GTE will land on the first dup for the matching key, while LT and 183 * LTE will land on the last dup for the matching key. 184 * 185 * search() and searchBoth() in this class may eventually be exposed as 186 * public JE Cursor methods, but this isn't practical now for the following 187 * reasons: 188 * 189 * + The API design needs more thought. Perhaps Search.EQ should be added. 190 * Perhaps existing Cursor methods should be deprecated. 191 * 192 * + This implementation moves the cursor multiple times and does not 193 * release locks on the intermediate records. 194 * 195 * + This could be implemented more efficiently using lower level cursor 196 * code. For example, an LTE search would actually more efficient than 197 * the existing GTE search (getSearchKeyRange and getSearchBothRange). 198 * 199 * These methods are used by KVStore. 200 */ search( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry pKey, final DatabaseEntry data, final Search searchMode, final LockMode lockMode)201 public static OperationStatus search( 202 final Cursor cursor, 203 final DatabaseEntry key, 204 final DatabaseEntry pKey, 205 final DatabaseEntry data, 206 final Search searchMode, 207 final LockMode lockMode) { 208 209 final DatabaseImpl dbImpl = cursor.getDatabaseImpl(); 210 KeyRange range = new KeyRange(dbImpl.getBtreeComparator()); 211 final boolean first; 212 213 switch (searchMode) { 214 case GT: 215 case GTE: 216 range = range.subRange( 217 key, searchMode == Search.GTE, null, false); 218 first = true; 219 break; 220 case LT: 221 case LTE: 222 range = range.subRange( 223 null, false, key, searchMode == Search.LTE); 224 first = false; 225 break; 226 default: 227 throw EnvironmentFailureException.unexpectedState(); 228 } 229 230 final RangeCursor rangeCursor = new RangeCursor( 231 range, null, dbImpl.getSortedDuplicates(), cursor); 232 233 final OperationStatus status = (first) ? 234 rangeCursor.getFirst(key, pKey, data, lockMode) : 235 rangeCursor.getLast(key, pKey, data, lockMode); 236 237 /* RangeCursor should not have dup'd the cursor. */ 238 assert cursor == rangeCursor.getCursor(); 239 240 return status; 241 } 242 243 /** 244 * Searches with the dups for the given key and finds the dup matching the 245 * pKey value, according to the Search param. 246 * 247 * See search() for more discussion. 248 */ searchBoth( final Cursor cursor, final DatabaseEntry key, final DatabaseEntry pKey, final DatabaseEntry data, final Search searchMode, final LockMode lockMode)249 public static OperationStatus searchBoth( 250 final Cursor cursor, 251 final DatabaseEntry key, 252 final DatabaseEntry pKey, 253 final DatabaseEntry data, 254 final Search searchMode, 255 final LockMode lockMode) { 256 257 final DatabaseImpl dbImpl = cursor.getDatabaseImpl(); 258 KeyRange range = new KeyRange(dbImpl.getBtreeComparator()); 259 range = range.subRange(key); 260 KeyRange pKeyRange = new KeyRange(dbImpl.getDuplicateComparator()); 261 final boolean first; 262 263 switch (searchMode) { 264 case GT: 265 case GTE: 266 pKeyRange = pKeyRange.subRange( 267 pKey, searchMode == Search.GTE, null, false); 268 first = true; 269 break; 270 case LT: 271 case LTE: 272 pKeyRange = pKeyRange.subRange( 273 null, false, pKey, searchMode == Search.LTE); 274 first = false; 275 break; 276 default: 277 throw EnvironmentFailureException.unexpectedState(); 278 } 279 280 final RangeCursor rangeCursor = new RangeCursor( 281 range, pKeyRange, dbImpl.getSortedDuplicates(), cursor); 282 283 final OperationStatus status = (first) ? 284 rangeCursor.getFirst(key, pKey, data, lockMode) : 285 rangeCursor.getLast(key, pKey, data, lockMode); 286 287 /* RangeCursor should not have dup'd the cursor. */ 288 assert cursor == rangeCursor.getCursor(); 289 290 return status; 291 } 292 293 /** 294 * Proxy to Cursor.getCursorImpl() 295 */ getCursorImpl(Cursor cursor)296 public static CursorImpl getCursorImpl(Cursor cursor) { 297 return cursor.getCursorImpl(); 298 } 299 300 /** 301 * Create a Cursor for internal use from a DatabaseImpl. 302 */ makeCursor(final DatabaseImpl databaseImpl, final Locker locker, final CursorConfig cursorConfig)303 public static Cursor makeCursor(final DatabaseImpl databaseImpl, 304 final Locker locker, 305 final CursorConfig cursorConfig) { 306 final Cursor cursor = new Cursor(databaseImpl, locker, cursorConfig, 307 true /* retainNonTxnLocks */); 308 /* Internal cursors don't need to be sticky. */ 309 cursor.setNonSticky(true); 310 return cursor; 311 } 312 313 /** 314 * @deprecated use {@link CursorConfig#setNonSticky} instead. 315 */ setNonCloning(final Cursor cursor, final boolean nonSticky)316 public static void setNonCloning(final Cursor cursor, 317 final boolean nonSticky) { 318 cursor.setNonSticky(nonSticky); 319 } 320 321 /** 322 * Proxy to Database.getDatabaseImpl() 323 */ getDatabaseImpl(final Database db)324 public static DatabaseImpl getDatabaseImpl(final Database db) { 325 return db.getDatabaseImpl(); 326 } 327 328 /** 329 * Proxy to JoinCursor.getSortedCursors() 330 */ getSortedCursors(final JoinCursor cursor)331 public static Cursor[] getSortedCursors(final JoinCursor cursor) { 332 return cursor.getSortedCursors(); 333 } 334 335 /** 336 * Proxy to EnvironmentConfig.setLoadPropertyFile() 337 */ setLoadPropertyFile(final EnvironmentConfig config, final boolean loadProperties)338 public static void setLoadPropertyFile(final EnvironmentConfig config, 339 final boolean loadProperties) { 340 config.setLoadPropertyFile(loadProperties); 341 } 342 343 /** 344 * Proxy to EnvironmentConfig.setCreateUP() 345 */ setCreateUP(final EnvironmentConfig config, final boolean checkpointUP)346 public static void setCreateUP(final EnvironmentConfig config, 347 final boolean checkpointUP) { 348 config.setCreateUP(checkpointUP); 349 } 350 351 /** 352 * Proxy to EnvironmentConfig.getCreateUP() 353 */ getCreateUP(final EnvironmentConfig config)354 public static boolean getCreateUP(final EnvironmentConfig config) { 355 return config.getCreateUP(); 356 } 357 358 /** 359 * Proxy to EnvironmentConfig.setCheckpointUP() 360 */ setCheckpointUP(final EnvironmentConfig config, final boolean checkpointUP)361 public static void setCheckpointUP(final EnvironmentConfig config, 362 final boolean checkpointUP) { 363 config.setCheckpointUP(checkpointUP); 364 } 365 366 /** 367 * Proxy to EnvironmentConfig.getCheckpointUP() 368 */ getCheckpointUP(final EnvironmentConfig config)369 public static boolean getCheckpointUP(final EnvironmentConfig config) { 370 return config.getCheckpointUP(); 371 } 372 373 /** 374 * Proxy to EnvironmentConfig.setTxnReadCommitted() 375 */ setTxnReadCommitted(final EnvironmentConfig config, final boolean txnReadCommitted)376 public static void setTxnReadCommitted(final EnvironmentConfig config, 377 final boolean txnReadCommitted) { 378 config.setTxnReadCommitted(txnReadCommitted); 379 } 380 381 /** 382 * Proxy to EnvironmentConfig.setTxnReadCommitted() 383 */ getTxnReadCommitted(final EnvironmentConfig config)384 public static boolean getTxnReadCommitted(final EnvironmentConfig config) { 385 return config.getTxnReadCommitted(); 386 } 387 388 /** 389 * Proxy to EnvironmentMutableConfig.cloneMutableConfig() 390 */ 391 public static EnvironmentMutableConfig cloneMutableConfig(final EnvironmentMutableConfig config)392 cloneMutableConfig(final EnvironmentMutableConfig config) { 393 return config.cloneMutableConfig(); 394 } 395 396 /** 397 * Proxy to EnvironmentMutableConfig.checkImmutablePropsForEquality() 398 */ 399 public static void checkImmutablePropsForEquality(final EnvironmentMutableConfig config, final Properties handleConfigProps)400 checkImmutablePropsForEquality(final EnvironmentMutableConfig config, 401 final Properties handleConfigProps) 402 throws IllegalArgumentException { 403 404 config.checkImmutablePropsForEquality(handleConfigProps); 405 } 406 407 /** 408 * Proxy to EnvironmentMutableConfig.copyMutablePropsTo() 409 */ 410 public static void copyMutablePropsTo(final EnvironmentMutableConfig config, final EnvironmentMutableConfig toConfig)411 copyMutablePropsTo(final EnvironmentMutableConfig config, 412 final EnvironmentMutableConfig toConfig) { 413 config.copyMutablePropsTo(toConfig); 414 } 415 416 /** 417 * Proxy to EnvironmentMutableConfig.validateParams. 418 */ 419 public static void disableParameterValidation(final EnvironmentMutableConfig config)420 disableParameterValidation(final EnvironmentMutableConfig config) { 421 config.setValidateParams(false); 422 } 423 424 /** 425 * Proxy to EnvironmentMutableConfig.getProps 426 */ getProps(final EnvironmentMutableConfig config)427 public static Properties getProps(final EnvironmentMutableConfig config) { 428 return config.getProps(); 429 } 430 431 /** 432 * Proxy to DatabaseConfig.setUseExistingConfig() 433 */ setUseExistingConfig(final DatabaseConfig config, final boolean useExistingConfig)434 public static void setUseExistingConfig(final DatabaseConfig config, 435 final boolean useExistingConfig) { 436 config.setUseExistingConfig(useExistingConfig); 437 } 438 439 /** 440 * Proxy to DatabaseConfig.validate(DatabaseConfig() 441 */ validate(final DatabaseConfig config1, final DatabaseConfig config2)442 public static void validate(final DatabaseConfig config1, 443 final DatabaseConfig config2) 444 throws DatabaseException { 445 446 config1.validate(config2); 447 } 448 449 /** 450 * Proxy to Transaction.getLocker() 451 */ getLocker(final Transaction txn)452 public static Locker getLocker(final Transaction txn) 453 throws DatabaseException { 454 455 return txn.getLocker(); 456 } 457 458 /** 459 * Proxy to Transaction.getEnvironment() 460 */ getEnvironment(final Transaction txn)461 public static Environment getEnvironment(final Transaction txn) 462 throws DatabaseException { 463 464 return txn.getEnvironment(); 465 } 466 467 /** 468 * Proxy to Environment.getDefaultTxnConfig() 469 */ 470 public static TransactionConfig getDefaultTxnConfig(final Environment env)471 getDefaultTxnConfig(final Environment env) { 472 return env.getDefaultTxnConfig(); 473 } 474 475 /** 476 * Get an Environment only if the environment is already open. This 477 * will register this Environment in the EnvironmentImpl's reference count, 478 * but will not configure the environment. 479 * @return null if the environment is not already open. 480 */ getEnvironmentShell(final File environmentHome)481 public static Environment getEnvironmentShell(final File environmentHome) { 482 final Environment env = new Environment(environmentHome); 483 if (env.isValid()) { 484 return env; 485 } 486 return null; 487 } 488 openInternalDatabase(final Environment env, final Transaction txn, final String databaseName, final DatabaseConfig config)489 public static Database openInternalDatabase(final Environment env, 490 final Transaction txn, 491 final String databaseName, 492 final DatabaseConfig config) { 493 return env.openInternalDatabase(txn, databaseName, config); 494 } 495 496 public static Transaction beginInternalTransaction(final Environment env, final TransactionConfig config)497 beginInternalTransaction(final Environment env, 498 final TransactionConfig config) { 499 return env.beginInternalTransaction(config); 500 } 501 makeExceptionEvent(final Exception e, final String n)502 public static ExceptionEvent makeExceptionEvent(final Exception e, 503 final String n) { 504 return new ExceptionEvent(e, n); 505 } 506 getTxn(final Transaction transaction)507 public static Txn getTxn(final Transaction transaction) { 508 return transaction.getTxn(); 509 } 510 511 public static DiskOrderedCursorImpl getDiskOrderedCursorImpl(final DiskOrderedCursor cursor)512 getDiskOrderedCursorImpl(final DiskOrderedCursor cursor) { 513 514 return cursor.getCursorImpl(); 515 } 516 } 517