|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.util.AbstractMap<K,V> org.archive.util.CachedBdbMap<K,V>
public class CachedBdbMap<K,V>
A BDB JE backed hashmap. It extends the normal BDB JE map implementation by holding a cache of soft referenced objects. That is objects are not written to disk until they are not referenced by any other object and therefore can be Garbage Collected.
BDB Java Edition is actually a btree. Flush to disk can be forced by sync(). To ensure that changes/mutations to values in this map are coherent and consistent at the application level, it is assumed that the application level only mutates values that are in this map and does not retain references to values longer than necessary. This allows mappings to be persisted during GC without explicit transactions or write operations. There are two styles of CachedBdbMap usage: 1. single threaded (or externally synchronized) activity that uses any Map and ConcurrentMap methods available and specifically requires remove(). 2. concurrent, high volume, accretive-only activity that usesputIfAbsent(K, V)
, but not the put(K, V)
, the replace(K, V, V)
or 1 arg remove(java.lang.Object)
methods.
The concurrent replace(K, V, V)
methods can be used if application level logic
can rule out surprise unmapping of values between threads.
This usage style does not require locking memMap and diskMap together
to guarantee cache coherence and consistency.
Both styles rely on an internal expunge operation (or the explicit
sync()
) to save changes to values.
The single threaded case can also use put(K, V)
on top of an
existing entry as long as no thread retains the previous value instance.
Nested Class Summary | |
---|---|
protected static class |
CachedBdbMap.DbEnvironmentEntry
Deprecated. Simple structure to keep needed information about a DB Environment. |
protected class |
CachedBdbMap.LowMemoryCanary
Deprecated. |
Nested classes/interfaces inherited from class java.util.AbstractMap |
---|
java.util.AbstractMap.SimpleEntry<K,V>, java.util.AbstractMap.SimpleImmutableEntry<K,V> |
Nested classes/interfaces inherited from interface java.util.Map |
---|
java.util.Map.Entry<K,V> |
Field Summary | |
---|---|
protected java.lang.ref.SoftReference<CachedBdbMap.LowMemoryCanary> |
canary
Deprecated. |
protected com.sleepycat.je.Database |
db
Deprecated. The BDB JE database used for this instance. |
protected com.sleepycat.collections.StoredSortedMap |
diskMap
Deprecated. The Collection view of the BDB JE database used for this instance. |
protected java.util.concurrent.atomic.AtomicInteger |
diskMapSize
Deprecated. The number of objects in the diskMap StoredMap. |
protected java.util.concurrent.ConcurrentHashMap<K,org.archive.util.CachedBdbMap.SoftEntry<V>> |
memMap
Deprecated. The softreferenced cache of diskMap. |
protected static java.lang.reflect.Field |
referentField
Deprecated. Reference to the Reference#referent Field. |
protected java.lang.ref.ReferenceQueue<V> |
refQueue
Deprecated. |
Constructor Summary | |
---|---|
CachedBdbMap(java.io.File dbDir,
java.lang.String dbName,
java.lang.Class<K> keyClass,
java.lang.Class<V> valueClass)
Deprecated. A constructor for creating a new CachedBdbMap. |
|
CachedBdbMap(java.lang.String dbName)
Deprecated. Constructor. |
Method Summary | |
---|---|
void |
clear()
Deprecated. Note that a call to this method CLOSEs the underlying bdbje. |
void |
close()
Deprecated. close/release any associated resources |
boolean |
containsKey(java.lang.Object key)
Deprecated. |
boolean |
containsValue(java.lang.Object value)
Deprecated. |
protected com.sleepycat.collections.StoredSortedMap |
createDiskMap(com.sleepycat.je.Database database,
com.sleepycat.bind.serial.StoredClassCatalog classCatalog,
java.lang.Class keyClass,
java.lang.Class valueClass)
Deprecated. |
java.util.Set<java.util.Map.Entry<K,V>> |
entrySet()
Deprecated. |
protected void |
finalize()
Deprecated. |
V |
get(java.lang.Object object)
Deprecated. get the object under the given key/name |
protected java.lang.String |
getDatabaseName()
Deprecated. |
V |
getOrUse(K key,
Supplier<V> supplierOrNull)
Deprecated. ObjectIdentityCache get-or-atomic-create method. |
void |
initialize(com.sleepycat.je.Environment env,
java.lang.Class<? super V> valueClass,
com.sleepycat.bind.serial.StoredClassCatalog classCatalog)
Deprecated. Call this method when you have an instance when you used the default constructor or when you have a deserialized instance that you want to reconnect with an extant bdbje environment. |
protected void |
initializeInstance()
Deprecated. Do any instance setup. |
protected void |
initTransientStats()
Deprecated. |
java.util.Set<K> |
keySet()
Deprecated. The keySet of the diskMap is all relevant keys. |
protected com.sleepycat.je.Database |
openDatabase(com.sleepycat.je.Environment environment,
java.lang.String dbName)
Deprecated. |
V |
put(K key,
V value)
Deprecated. Map.put() implementation. |
V |
putIfAbsent(K key,
V value)
Deprecated. A composite putIfAbsent() over memMap and diskMap. |
V |
remove(java.lang.Object key)
Deprecated. Remove mapping for the given key. |
boolean |
remove(java.lang.Object key,
java.lang.Object value)
Deprecated. remove item matching both the key and value. |
V |
replace(K key,
V value)
Deprecated. Replace entry for key only if currently mapped to some value. |
boolean |
replace(K key,
V oldValue,
V newValue)
Deprecated. Replace entry for key only if currently mapped to given value. |
int |
size()
Deprecated. count of name-to-object contained |
void |
sync()
Deprecated. Sync in-memory map entries to backing disk store. |
Methods inherited from class java.util.AbstractMap |
---|
clone, equals, hashCode, isEmpty, putAll, toString, values |
Methods inherited from class java.lang.Object |
---|
getClass, notify, notifyAll, wait, wait, wait |
Methods inherited from interface java.util.Map |
---|
equals, hashCode, isEmpty, putAll, values |
Field Detail |
---|
protected transient com.sleepycat.je.Database db
protected transient com.sleepycat.collections.StoredSortedMap diskMap
protected transient java.util.concurrent.ConcurrentHashMap<K,org.archive.util.CachedBdbMap.SoftEntry<V>> memMap
1. Swap in/First insert: diskMap, then memMap // putIfAbsent() assures atomicity. 2. Value mutation: only one value instance per key in memMap is maintained so identity compare of value works and all clients operate on the same object. This implies that methods which change the instance (replace() methods) are not compatible with this design and should only be used if instance of CachedBdbMap is used by a single thread. Because content of referent is mutated, mapping is not changed; 2.1. BDB JE operation assumption: calling get(k) twice returns values that are equals(), but not necessarily == by identity ( diskMap.get(k).equals(diskMap.get(k)) is true, but diskMap.get(k) != diskMap.get(k) (might be, but not guaranteed)). 3. Swap out/flush: diskMap update, then memMap remove: diskMap.put(k,v2); // exclusive only if performed when processing ref queue during expunge; Avoid expunge races with a countdown latch in SoftEntry; memMap.remove(k,v2); if memMap race lost, then no harm done (notice that (k,v2) could match in either diskMap or memMap, or both, or neither). 3.1. Only expunge does an update of an existing diskMap entry for concurrent methods. 3.2. CachedBdbMap.get() must be able to return referent or otherwise effect a swap-in if get() is invoked during a swap out of a particular key-value entry. 4. sync() to disk: synchronized sync() // fully locked, no races.See the "find or create" style cache
ServerCache.getServerFor(CandidateURI)
for the major
high-concurrency client of this class in terms of number of objects
stored and performance impact.
protected transient java.lang.ref.ReferenceQueue<V> refQueue
protected java.util.concurrent.atomic.AtomicInteger diskMapSize
protected static java.lang.reflect.Field referentField
protected transient java.lang.ref.SoftReference<CachedBdbMap.LowMemoryCanary> canary
Constructor Detail |
---|
public CachedBdbMap(java.lang.String dbName)
#initialize(Environment, Class, Class, StoredClassCatalog)
to finish construction. Construction is two-stepped to support
reconnecting a deserialized CachedBdbMap with its backing bdbje
database.
dbName
- Name of the backing db this instance should use.public CachedBdbMap(java.io.File dbDir, java.lang.String dbName, java.lang.Class<K> keyClass, java.lang.Class<V> valueClass) throws com.sleepycat.je.DatabaseException
This constructor internally calls
#initialize(Environment, Class, Class, StoredClassCatalog)
.
Do not call initialize if you use this constructor.
dbDir
- The directory where the database will be created.dbName
- The name of the database to back this map by.keyClass
- The class of the objects allowed as keys.valueClass
- The class of the objects allowed as values.
com.sleepycat.je.DatabaseException
- is thrown if the underlying BDB JE database
throws an exception.Method Detail |
---|
public void initialize(com.sleepycat.je.Environment env, java.lang.Class<? super V> valueClass, com.sleepycat.bind.serial.StoredClassCatalog classCatalog) throws com.sleepycat.je.DatabaseException
CachedBdbMap(File, String, Class, Class)
constructor.
env
- keyClass
- valueClass
- classCatalog
-
com.sleepycat.je.DatabaseException
protected void initializeInstance()
protected void initTransientStats()
protected com.sleepycat.collections.StoredSortedMap createDiskMap(com.sleepycat.je.Database database, com.sleepycat.bind.serial.StoredClassCatalog classCatalog, java.lang.Class keyClass, java.lang.Class valueClass)
protected com.sleepycat.je.Database openDatabase(com.sleepycat.je.Environment environment, java.lang.String dbName) throws com.sleepycat.je.DatabaseException
com.sleepycat.je.DatabaseException
public void close()
ObjectIdentityCache
close
in interface java.io.Closeable
close
in interface ObjectIdentityCache<K,V>
protected void finalize() throws java.lang.Throwable
finalize
in class java.lang.Object
java.lang.Throwable
public java.util.Set<K> keySet()
keySet
in interface java.util.Map<K,V>
keySet
in interface ObjectIdentityCache<K,V>
keySet
in class java.util.AbstractMap<K,V>
Map.keySet()
public java.util.Set<java.util.Map.Entry<K,V>> entrySet()
entrySet
in interface java.util.Map<K,V>
entrySet
in class java.util.AbstractMap<K,V>
public V getOrUse(K key, Supplier<V> supplierOrNull)
getOrUse
in interface ObjectIdentityCache<K,V>
public V get(java.lang.Object object)
ObjectIdentityCache
get
in interface java.util.Map<K,V>
get
in interface ObjectIdentityCache<K,V>
get
in class java.util.AbstractMap<K,V>
public V put(K key, V value)
putIfAbsent(K, V)
instead.
Preconditions: (diskMap.containsKey(), memMap.containsKey()) are: (*,*) put() cannot assure "only expose one value instance", so all cases are the same: put to diskMap then memMap; clear any pre-existing SoftEntry to prevent expunge of old value. PostConditions: (T,T) both memMap and diskMap will have entries for given key; if null is returned, then this is the first time the key has an entry, otherwise the previous value in diskMap will not be updated until expunge.
put
in interface java.util.Map<K,V>
put
in class java.util.AbstractMap<K,V>
key
- value
-
public boolean replace(K key, V oldValue, V newValue)
Preconditions: (diskMap.containsKey(), memMap.containsKey()) are: (F,F) nothing to replace. PostCondition: (F,F) no replace. (T,F) value must be swapped-in, do replace(), PostCondition: (T,T) if replace occurred or not (value might have been replaced), diskMap need not be updated because expunge will do that. (*,T) normal swapped-in condition (we can assume that the method which put a mapping to memMap took care of creating one for diskMap), memMap value is most recent and expunge can take care of updating diskMap, so we only do replace() on memMap; PostCondition: (*,T).
replace
in interface java.util.concurrent.ConcurrentMap<K,V>
public V replace(K key, V value)
Preconditions: (diskMap.containsKey(), memMap.containsKey()) are: (F,F) nothing to replace. PostCondition: (F,F) no change. (T,F) value must be swapped-in, do replace(), PostCondition: (T,T) if replace occurred or not (value might have been replaced), diskMap need not be updated because expunge will do that. (*,T) normal swapped-in condition (we can assume that the method which put a mapping to memMap took care of creating one for diskMap), memMap value is most recent and expunge can take care of updating diskMap, so we only do replace() on memMap.
replace
in interface java.util.concurrent.ConcurrentMap<K,V>
public V putIfAbsent(K key, V value)
Preconditions: (diskMap.containsKey(), memMap.containsKey(SoftEntry)) are: (F,F) initial starting conditions: is absent, put to diskMap then memMap. (F,T) transient remove(): await other thread to finish with memMap, then proceed as (F,F) OR (if remove not used) an unexpected data race occurred. (T,F) reloadable from disk or in process of inserting first time: not absent. (T,T) normal swapped in condition: not absent. PostConditions: (T,T) both memMap and diskMap will have entries for given key (if null is returned, then the value given is the one mapped).
putIfAbsent
in interface java.util.concurrent.ConcurrentMap<K,V>
key
- value
- the value to which the given key should map, but only
if there is existing mapping for key.
public void clear()
clear
in interface java.util.Map<K,V>
clear
in class java.util.AbstractMap<K,V>
public V remove(java.lang.Object key)
Preconditions: (diskMap.containsKey(), memMap.containsKey(SoftEntry)) are: (F,*) nothing to remove if diskMap has no entry. (T,F) remove from diskMap, await expunge in memMap, if in progress. (T,T) remove from diskMap, clear phantom to prevent expunge of memMap. PostConditions: (F,F) both memMap and diskMap will NOT have entries for given key (if null is returned, then nothing was removed).
remove
in interface java.util.Map<K,V>
remove
in class java.util.AbstractMap<K,V>
key
-
public boolean remove(java.lang.Object key, java.lang.Object value)
Preconditions: (diskMap.containsKey() AND value.equals(V), memMap.containsKey(SoftEntry) AND value.equals(V) AND swapped-in) are: (F,F) nothing to do. (F,T) diskMap.remove(K,V) fails, but memMap.remove(K,V) still possible (T,F) remove from diskMap, await expunge in memMap, if in progress. (T,T) remove from diskMap, clear phantom to prevent expunge of memMap. PostConditions: (F,F) both memMap and diskMap will NOT have entries for given key (if false is returned, then nothing was removed).
remove
in interface java.util.concurrent.ConcurrentMap<K,V>
key
- key used for matching mapping to remove.value
- value used for matching mapping to remove.
public boolean containsKey(java.lang.Object key)
containsKey
in interface java.util.Map<K,V>
containsKey
in class java.util.AbstractMap<K,V>
public boolean containsValue(java.lang.Object value)
containsValue
in interface java.util.Map<K,V>
containsValue
in class java.util.AbstractMap<K,V>
value
-
public int size()
ObjectIdentityCache
size
in interface java.util.Map<K,V>
size
in interface ObjectIdentityCache<K,V>
size
in class java.util.AbstractMap<K,V>
protected java.lang.String getDatabaseName()
public void sync()
sync
in interface ObjectIdentityCache<K,V>
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |