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 package com.sleepycat.je;
8 
9 /**
10  * Modes that can be specified for control over caching of records in the JE
11  * in-memory cache.  When a record is stored or retrieved, the cache mode
12  * determines how long the record is subsequently retained in the JE in-memory
13  * cache, relative to other records in the cache.
14  *
15  * <p>When the cache overflows, JE must evict some records from the cache.  By
16  * default, JE uses a Least Recently Used (LRU) algorithm for determining which
17  * records to evict.  With the LRU algorithm, JE makes a best effort to evict
18  * the "coldest" (least recently used or accessed) records and to retain the
19  * "hottest" records in the cache for as long as possible.</p>
20  *
21  * <p>Note that JE makes a best effort to implement an approximation of an LRU
22  * algorithm, and the very coldest record is not always evicted from the cache
23  * first.  In addition, hotness and coldness are applied to the portion of the
24  * in-memory BTree that is accessed to perform the operation, not just to the
25  * record itself.</p>
26  *
27  * <p>A non-default cache mode may be explicitly specified to override the
28  * default behavior of the LRU algorithm.  When no cache mode is explicitly
29  * specified, the default cache mode is {@link #DEFAULT}.  The default mode
30  * causes the normal LRU algorithm to be used.</p>
31  *
32  * <p>An explicit cache mode may be specified as an {@link
33  * EnvironmentConfig#setCacheMode Environment property}, a {@link
34  * DatabaseConfig#setCacheMode Database property}, or a {@link
35  * Cursor#setCacheMode Cursor property}.  If none are specified, {@link
36  * #DEFAULT} is used.  If more than one non-null property is specified, the
37  * Cursor property overrides the Database and Environment properties, and the
38  * Database property overrides the Environment property.</p>
39  *
40  * <p>When all records in a given Database, or all Databases, should be treated
41  * the same with respect to caching, using the Database and/or Environment
42  * cache mode properties is sufficient. For applications that need finer
43  * grained control, the Cursor cache mode property can be used to provide a
44  * specific cache mode for individual records or operations.  The Cursor cache
45  * mode property can be changed at any time, and the cache mode specified will
46  * apply to subsequent operations performed with that Cursor.</p>
47  *
48  * <p>In a Replicated Environment where a non-default cache mode is desired,
49  * the cache mode can be configured on the Master node as described above.
50  * However, it is important to configure the cache mode on the Replica nodes
51  * using an Environment property.  That way, the cache mode will apply to
52  * <em>write</em> operations that are replayed on the Replica for all
53  * Databases, even if the Databases are not open by the application on the
54  * Replica.  Since all nodes may be Replicas at some point in their life cycle,
55  * it is recommended to configure the desired cache mode as an Environment
56  * property on all nodes in a Replicated Environment.</p>
57  *
58  * <p>On a Replica, per-Database control over the cache mode for <em>write</em>
59  * operations is possible by opening the Database on the Replica and
60  * configuring the cache mode.  Per-Cursor control (meaning per-record or
61  * per-operation) control of the cache mode is not possible on a Replica for
62  * <em>write</em> operations.  For <em>read</em> operations, both per-Database
63  * and per-Cursor control is possible on the Replica, as described above.</p>
64  * <p>
65  * The cache related stats in {@link EnvironmentStats} can provide some measure
66  * of the effectiveness of the cache mode choice.
67  */
68 public enum CacheMode {
69 
70     /**
71      * The record's hotness is changed to "most recently used" by the operation
72      * where this cache mode is specified.
73      *
74      * <p>The record will always be colder than other records accessed with a
75      * {@code KEEP_HOT} cache mode, and hotter than other records accessed with
76      * a {@code MAKE_COLD} cache mode.  Among records accessed with the {@code
77      * DEFAULT} cache mode, the record will be hotter than other records
78      * accessed at an earlier time and colder then other records accessed at a
79      * later time.</p>
80      *
81      * <p>This cache mode is used when the application does not need explicit
82      * control over the cache and a standard LRU implementation is
83      * sufficient.</p>
84      */
85     DEFAULT,
86 
87     /**
88      * The record is assigned "maximum hotness" by the operation where this
89      * cache mode is specified.
90      *
91      * <p>The record will have the same hotness as other records accessed with
92      * this cache mode.  Its relative hotness will not be reduced over time as
93      * other records are accessed.  It can only become colder over time if it
94      * is subsequently accessed with the {@code DEFAULT} or {@code MAKE_COLD}
95      * cache mode.</p>
96      *
97      * <p>This cache mode is normally used when the application intends to
98      * access this record again soon.</p>
99      */
100     KEEP_HOT,
101 
102     /**
103      * The record's hotness or coldness is unchanged by the operation where
104      * this cache mode is specified.
105      *
106      * <p>If the record was present in the cache prior to this operation, then
107      * its pre-existing hotness or coldness will not be changed.  If the record
108      * was added to the cache by this operation, it will have "maximum
109      * coldness" and will therefore be colder than other records.</p>
110      *
111      * <p>This cache mode is normally used when the application prefers that
112      * the record be evicted from the cache when space is needed, but only if
113      * the record has not been accessed using {@code DEFAULT} or {@code
114      * KEEP_HOT} recently.</p>
115      */
116     UNCHANGED,
117 
118     /**
119      * The record is assigned "maximum coldness" by the operation where this
120      * cache mode is specified.  When the JE cache is full, operations using
121      * this cache mode will opportunistically perform explicit eviction of the
122      * the record LN (leaf node) and/or its parent BIN (bottom internal node).
123      *
124      * <p>If the record is not evicted (because the JE cache is not full), the
125      * record will have the same hotness as other records accessed with this
126      * cache mode.  It is very likely that this record will be evicted from the
127      * cache when the cache fills.  It can only become warmer over time if it
128      * is subsequently accessed with the {@code DEFAULT} or {@code KEEP_HOT}
129      * cache mode.</p>
130      *
131      * <p>This cache mode is normally used when the application prefers that
132      * the record be evicted from the cache when space is needed, regardless of
133      * whether the record has been accessed using {@code DEFAULT} or
134      * {@code KEEP_HOT} recently.</p>
135      *
136      * <p>A potential advantage of this cache mode is that blocking between
137      * threads may be reduced when eviction is a dominant performance factor.
138      * Blocking during eviction is uncommon but can occur if many threads are
139      * evicting concurrently.</p>
140      *
141      * @since 3.3.98
142      */
143     MAKE_COLD,
144 
145     /**
146      * The record LN (leaf node) is evicted as soon as possible after the
147      * operation where this cache mode is specified.  The hotness of the
148      * parent BIN (bottom internal node) for the record is changed to "most
149      * recently used" as if {@code DEFAULT} were used.
150      *
151      * <p>When a cursor is used, the LN is evicted only when the cursor is
152      * moved to a different record or is closed.</p>
153      *
154      * <p>This cache mode is normally used when not all LNs will fit into the
155      * JE cache, and the application prefers to read the LN from the log file
156      * when the record is accessed again, rather than have it take up space in
157      * the JE cache and potentially cause expensive Java GC.</p>
158      *
159      * <p>A potential advantage of this cache mode is that blocking between
160      * threads may be reduced when eviction is a dominant performance factor.
161      * Blocking during eviction is uncommon but can occur if many threads are
162      * evicting concurrently.</p>
163      *
164      * <p>Note that using this mode for all operations will prevent the cache
165      * from filling, if all internal nodes fit in cache.</p>
166      *
167      * @since 3.3.98
168      */
169     EVICT_LN,
170 
171     /**
172      * The record LN (leaf node) and its parent BIN (bottom internal node)
173      * are evicted as soon as possible after the operation where this cache
174      * mode is specified.  Note that when the BIN is evicted, all record LNs
175      * (leaf nodes) in that BIN are also evicted.  If the BIN cannot be evicted
176      * immediately, it is assigned "maximum coldness" as if {@code MAKE_COLD}
177      * were used.
178      *
179      * <p>When a cursor is used, the LN is evicted when the cursor is moved to
180      * a different record or is closed.  The BIN is evicted when the cursor
181      * moves to a different BIN or is closed.</p>
182 
183      * <p>This cache mode is normally used when not all BINs will fit into the
184      * JE cache, and the application prefers to read the LN and BIN from the
185      * log file when the record is accessed again, rather than have them take
186      * up space in the JE cache and potentially cause expensive Java GC.</p>
187      *
188      * <p>A potential advantage of this cache mode is that blocking between
189      * threads may be reduced when eviction is a dominant performance factor.
190      * Blocking during eviction is uncommon but can occur if many threads are
191      * evicting concurrently.</p>
192      *
193      * <p>Note that using this mode for all operations will prevent the cache
194      * from filling, if all non-bottom internal nodes fit in cache.</p>
195      *
196      * @since 4.0.97
197      */
198     EVICT_BIN,
199 
200     /**
201      * @hidden
202      * For internal use only.
203      *
204      * The {@code CacheMode} is determined dynamically by a {@link
205      * CacheModeStrategy} object.  The {@link CacheModeStrategy#getCacheMode}
206      * method is called for every database operation to obtain the cache mode.
207      * The strategy implementation may use any algorithm desired to determine
208      * the cache mode to be used.
209      *
210      * <p>When using this cache mode, a {@link CacheModeStrategy} must be
211      * configured using a {@link DatabaseConfig#setCacheModeStrategy Database
212      * property} or an {@link EnvironmentConfig#setCacheModeStrategy
213      * Environment property}.  If both are specified, the Database property
214      * overrides the Environment property.</p>
215      *
216      * <p>Note that the strategy object and the {@code DYNAMIC} cache mode need
217      * not both be configured at the same level (Environment or Database).
218      * These two properties may be independently configured.  The {@code
219      * DYNAMIC} cache mode may be configured for a Cursor, Database or
220      * Environment, and the strategy object may be configured for a Database or
221      * Environment.</p>
222      *
223      * @since 4.0.97
224      */
225     DYNAMIC
226 }
227