|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectedu.harvard.deas.hyperenc.PersistentMap<K,V>
public class PersistentMap<K,V>
A map that is stored persistently on disk in a database. A persistent map is a sorted map that is stored in a Berkeley database on disk so that it can be used across multiple instances of a program, or transferred between different clients on different machines.
Each persistent map has a name; no two persistent maps may have the same
name. Clients request a map with a particular name using
getInstance
. If a map by that name already exists, the existing
map is returned. Otherwise, a new map is constructed and returned.
The Berkeley DB JE Collections API does not support Map.size()
because the operation would be prohibitively expensive to perform reliably on
the database. As such, this class keeps track of its own size, maintaining
the size data when an element is inserted or removed. This means that it is
important that there be only one map object per underlying database (although
multiple threads may have a reference to the single map, which is
thread-safe): getInstance
ensures that this is true.
This implementation forces all data to disk (using
) every time the map is changed. This
synchronous I/O incurs a performance penalty, but is necessary to ensure
security. Consider an example of a problem that could occur with asynchronous
I/O: a user encrypts a message using blocks stored in a PersistentMap, and
e-mails the encrypted message to a friend. Then, the power fails after the
message is sent, but before the database updates are written to disk. The
ciphertext is now public, but the fact that certain encryption blocks were
used was not recorded to disk, so those blocks will be used again the next
time the program is run!
Environment.sync()
)
An alternative approach would be to require that the caller sync the Environment before externally-visible I/O (such as an e-mail). The synchronous I/O strategy is less prone to error, so we'll use it unless performance suffers too greatly.
This map does not allow null values.
Thread safety: PersistentMap is unconditionally thread-safe. The
keySet
and values
methods return collections that
are not backed by the map, so there is no need to synchronize on the map when
iterating over them.
Field Summary | |
---|---|
static File |
DEFAULT_HOME
The location on disk of the default database. |
Method Summary | ||
---|---|---|
boolean |
containsKey(K key)
Same as Map.containsKey(java.lang.Object) . |
|
K |
firstKey()
Returns the first (lowest) key currently in this map. |
|
V |
get(K key)
Same as Map.get(Object) . |
|
V |
getFirst()
Returns the element with the first (lowest) key currently in this map. |
|
static
|
getInstance(String name,
Class<K> keyClass,
Class<V> valueClass)
Return a map with the given name, creating it if necessary. |
|
static
|
getInstance(String name,
Class<K> keyClass,
Class<V> valueClass,
File environment)
Return a map with the given name, creating it if necessary. |
|
boolean |
isEmpty()
Returns true iff this map contains no elements. |
|
Set<K> |
keySet()
Returns a Set view of the keys contained in this map. |
|
K |
lastKey()
Returns the last (highest) key currently in this map. |
|
V |
put(K key,
V value)
Same as Map.put(Object,Object) . |
|
V |
remove(K key)
Same as Map.remove(Object) . |
|
V |
removeFirst()
Removes and returns the element with the first (lowest) key currently in this map. |
|
int |
size()
Returns the number of key-value mappings in this map. |
|
Collection<V> |
values()
Returns a Collection view of the values contained in this map. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final File DEFAULT_HOME
Method Detail |
---|
public static <K,V> PersistentMap<K,V> getInstance(String name, Class<K> keyClass, Class<V> valueClass, File environment)
If the key type or value type is a primitive, then a
TupleBinding
will be used as the binding, otherwise a
SerialBinding
will be used. In either case, K
and
V
must be serializable.
Note on type safety: This method will return map with type
parameters K and V, regardless of the actual type of the underlying
database. (It is somewhat difficult to actually enforce type safety
because the types stored in the database are not readily accessible.)
Attempts to read entries from the map that were not originally written
through a map with the same parameters K and V will likely throw an
IllegalArgumentException
.
name
- The name of the map. If there is another map by this name, it will
be returned. Otherwise, a new map will be created.keyClass
- The class of the keys of this map.valueClass
- The class of the values of this map.environment
- The path on disk of the database environment underlying the database
backing this map. Must be readable and writable. If it doesn't
exist, it will be created. If null
, the default
environment specified by DEFAULT_HOME
is used.
name
. If it didn't exist before, it
is created and returned.
IllegalArgumentException
- if the specified environment does not exist and could not be
created on disk, or if it exists and could not be opened.TupleBinding.getPrimitiveBinding(Class)
,
Environment
public static <K,V> PersistentMap<K,V> getInstance(String name, Class<K> keyClass, Class<V> valueClass)
getInstance(name, keyClass, valueClass, null)
.
public int size()
put
and remove
). It does not necessarily reflect
the on-disk state of the map.
Specific situations in which this size may not be accurate include:
keySet
or entrySet
methods
public V get(K key)
Map.get(Object)
.
public Set<K> keySet()
Set
view of the keys contained in this map. Same as
Map.keySet()
except that the returned set is not backed by
the map, so changes to the returned set are not reflected in the
original map.
public Collection<V> values()
Collection
view of the values contained in this map. Same
as Map.values()
except that the returned set is not backed
by the map, so changes to the returned set are not reflected in the
original map.
public V put(K key, V value)
Map.put(Object,Object)
. If value
was not already present in
the map, increments the size of this map by 1. Otherwise, doesn't change
the size of the map.
public boolean isEmpty()
true
iff this map contains no elements.
this.size() == 0
public V remove(K key)
Map.remove(Object)
. If value
was
present in the map, decrements the size of this map by 1. Otherwise,
doesn't change the size of the map.
public boolean containsKey(K key)
Map.containsKey(java.lang.Object)
.
public K firstKey()
SortedMap.firstKey()
.
NoSuchElementException
- if this map is emptypublic K lastKey()
SortedMap.lastKey()
.
NoSuchElementException
- if this map is emptypublic V getFirst()
this.get(this.firstKey())
, but is atomic.
public V removeFirst()
this.get(this.firstKey())
, but is
atomic.
NoSuchElementException
- if the map is empty
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |