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