public class FastMap<K,V> extends java.lang.Object implements java.util.Map<K,V>, Reusable, XMLSerializable, Realtime
This class represents a hash map with real-time behavior;
smooth capacity increase and thread-safe without external
synchronization when shared
.
FastMap
has a predictable iteration order, which is the order in
which keys are inserted into the map (similar to
java.util.LinkedHashMap
collection class). If the map is
marked shared
then all operations are
thread-safe including iterations over the map's collections.
Unlike ConcurrentHashMap
, access
never
blocks; retrieval reflects the map state not older than the last time the
accessing threads have been synchronized (for multi-processors systems
synchronizing ensures that the CPU internal cache is not stale).
In most application it is not a problem because thread synchronization
is done at high level (e.g. scheduler) and threads run freely
(and quickly) until the next synchronization point. In some cases the
"happen before" guarantee is necessary (e.g. to ensure unicity) and
threads have to be synchronized explicitly. Whenever possible such
synchronization should be performed on the key object itself and
not the whole map. For example:
FastMap<Index, Object> sparseVector = new FastMap<Index, Object>().shared()
... // Put
synchronized(index) { // javolution.util.Index instances are unique.
sparseVector.put(index, value);
}
... // Get
synchronized(index) { // Blocking only when accessing the same index.
value = sparseVector.get(index); // Latest value guaranteed.
}
FastMap
may use custom key comparators; the default comparator is
either DIRECT
or
REHASH
based upon the current Javolution
Configuration. Users may explicitly set the key comparator to
DIRECT
for optimum performance
when the hash codes are well distributed for all run-time platforms
(e.g. calculated hash codes).
Custom key comparators are extremely useful for value retrieval when
map's keys and argument keys are not of the same class (such as
String
and Text
(LEXICAL
)), to substitute more efficient
hash code calculations (STRING
)
or for identity maps (IDENTITY
):
FastMap identityMap = new FastMap().setKeyComparator(FastComparator.IDENTITY);
FastMap.Entry
can quickly be iterated over (forward or backward)
without using iterators. For example:
FastMap<String, Thread> map = ...;
for (FastMap.Entry<String, Thread> e = map.head(), end = map.tail(); (e = e.getNext()) != end;) {
String key = e.getKey(); // No typecast necessary.
Thread value = e.getValue(); // No typecast necessary.
}
Custom map implementations may override the newEntry()
method
in order to return their own FastMap.Entry
implementation (with
additional fields for example).
FastMap
are reusable
; they maintain an
internal pool of Map.Entry
objects. When an entry is removed
from a map, it is automatically restored to its pool. Any new entry is
allocated in the same memory area as the map itself (RTSJ). If the map
is shared, removed entries are not recycled but only dereferenced
(to maintain thread-safety)
Shared
maps do not use internal synchronization, except in case of
concurrent modifications of the map structure (entries being added/deleted).
Reads and iterations are never synchronized and never blocking.
With regards to the memory model, shared maps are equivalent to shared
non-volatile variables (no "happen before" guarantee). They can be used
as very efficient lookup tables. For example:
public class Unit {
static FastMap<Unit, String> labels = new FastMap().shared();
...
public String toString() {
String label = labels.get(this); // No synchronization.
if (label != null) return label;
label = makeLabel();
labels.put(this, label);
return label;
}
}
Implementation Note: To maintain time-determinism, rehash/resize is performed only when the map's size is small (see chart). For large maps (size > 512), the map is divided recursively into (64) smaller sub-maps. The cost of the dispatching (based upon hashcode value) has been measured to be at most 20% of the access time (and most often way less).
Modifier and Type | Class and Description |
---|---|
static class |
FastMap.Entry<K,V>
This class represents a
FastMap entry. |
Constructor and Description |
---|
FastMap()
Creates a map whose capacity increment smoothly without large resize
operations.
|
FastMap(int capacity)
Creates a map of specified maximum size (a full resize may occur if the
specififed capacity is exceeded).
|
FastMap(java.util.Map<? extends K,? extends V> map)
Creates a map containing the specified entries, in the order they
are returned by the map iterator.
|
FastMap(java.lang.String id)
Creates a persistent map associated to the specified unique identifier
(convenience method).
|
Modifier and Type | Method and Description |
---|---|
void |
clear()
Removes all map's entries.
|
boolean |
containsKey(java.lang.Object key)
Indicates if this map contains a mapping for the specified key.
|
boolean |
containsValue(java.lang.Object value)
Indicates if this map associates one or more keys to the specified value.
|
java.util.Set<java.util.Map.Entry<K,V>> |
entrySet()
Returns a
FastCollection view of the mappings contained in this
map. |
boolean |
equals(java.lang.Object obj)
Compares the specified object with this map for equality.
|
V |
get(java.lang.Object key)
Returns the value to which this map associates the specified key.
|
FastMap.Entry<K,V> |
getEntry(java.lang.Object key)
Returns the entry with the specified key.
|
FastComparator<? super K> |
getKeyComparator()
Returns the key comparator for this fast map.
|
FastComparator<? super V> |
getValueComparator()
Returns the value comparator for this fast map.
|
int |
hashCode()
Returns the hash code value for this map.
|
FastMap.Entry<K,V> |
head()
Returns the head entry of this map.
|
boolean |
isEmpty()
Indicates if this map contains no key-value mappings.
|
boolean |
isShared()
Indicates if this map supports concurrent operations without
synchronization (default unshared).
|
java.util.Set<K> |
keySet()
Returns a
FastCollection view of the keys contained in this
map. |
protected FastMap.Entry<K,V> |
newEntry()
Returns a new entry for this map; this method can be overriden by
custom map implementations.
|
static <K,V> FastMap<K,V> |
newInstance()
Returns a potentially
recycled map instance. |
void |
printStatistics(java.io.PrintStream out)
Prints the current statistics on this map.
|
V |
put(K key,
V value)
Associates the specified value with the specified key in this map.
|
void |
putAll(java.util.Map<? extends K,? extends V> map)
Copies all of the mappings from the specified map to this map.
|
FastMap.Entry<K,V> |
putEntry(K key,
V value)
Associates the specified value with the specified key in this map and
returns the corresponding entry.
|
V |
putIfAbsent(K key,
V value)
Associates the specified value only if the specified key is not already
associated.
|
static void |
recycle(FastMap instance)
Recycles the specified map instance.
|
V |
remove(java.lang.Object key)
Removes the entry for the specified key if present.
|
void |
reset()
Resets the internal state of this object to its default values.
|
FastMap<V,K> |
reverse()
Returns the reverse mapping of this map (for which the keys are this
map's values and the values are this map's keys).
|
FastMap<K,V> |
setKeyComparator(FastComparator<? super K> keyComparator)
Sets the key comparator for this fast map.
|
FastMap<K,V> |
setShared(boolean isShared)
Deprecated.
Replaced by
shared() |
FastMap<K,V> |
setValueComparator(FastComparator<? super V> valueComparator)
Sets the value comparator for this map.
|
FastMap<K,V> |
shared()
Sets the shared status of this map (whether the map is thread-safe
or not).
|
int |
size()
Returns the number of key-value mappings in this
FastMap . |
FastMap.Entry<K,V> |
tail()
Returns the tail entry of this map.
|
java.lang.String |
toString()
Returns the
String representation of this
FastMap . |
Text |
toText()
Returns the textual representation of this map.
|
java.util.Map<K,V> |
unmodifiable()
Returns the unmodifiable view associated to this map.
|
java.util.Collection<V> |
values()
Returns a
FastCollection view of the values contained in this
map. |
public FastMap()
public FastMap(java.lang.String id)
id
- the unique identifier for this map.java.lang.IllegalArgumentException
- if the identifier is not unique.PersistentContext.Reference
public FastMap(int capacity)
capacity
- the maximum capacity.public static <K,V> FastMap<K,V> newInstance()
recycled
map instance.public static void recycle(FastMap instance)
instance
- the map instance to recycle.public final FastMap<V,K> reverse()
public final FastMap.Entry<K,V> head()
head().getNext()
holds
the first map entry.public final FastMap.Entry<K,V> tail()
tail().getPrevious()
holds the last map entry.public final int size()
FastMap
.
Note: If concurrent updates are performed, application should not rely upon the size during iterations.
public final boolean isEmpty()
public final boolean containsKey(java.lang.Object key)
public final boolean containsValue(java.lang.Object value)
public final V get(java.lang.Object key)
shared
.public final FastMap.Entry<K,V> getEntry(java.lang.Object key)
key
- the key whose associated entry is to be returned.null
if none.public final V put(K key, V value)
shared
map, internal synchronization
is performed only when new entries are created.put
in interface java.util.Map<K,V>
key
- the key with which the specified value is to be associated.value
- the value to be associated with the specified key.null
if there was no mapping for key. A
null
return can also indicate that the map
previously associated null
with the specified key.java.lang.NullPointerException
- if the key is null
.public final FastMap.Entry<K,V> putEntry(K key, V value)
key
- the key with which the specified value is to be associated.value
- the value to be associated with the specified key.java.lang.NullPointerException
- if the key is null
.public final void putAll(java.util.Map<? extends K,? extends V> map)
public final V putIfAbsent(K key, V value)
if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
except that for shared maps the action is performed atomically.
For shared maps, this method guarantees that if two threads try to
put the same key concurrently only one of them will succeed.putIfAbsent
in interface java.util.Map<K,V>
key
- the key with which the specified value is to be associated.value
- the value to be associated with the specified key.null
if there was no mapping for key. A
null
return can also indicate that the map
previously associated null
with the specified key.java.lang.NullPointerException
- if the key is null
.public final V remove(java.lang.Object key)
shared
;
otherwise the entry is candidate for garbage collection.
Note: Shared maps in ImmortalMemory (e.g. static) should not remove
their entries as it could cause a memory leak (ImmortalMemory
is never garbage collected), instead they should set their
entry values to null
.
remove
in interface java.util.Map<K,V>
key
- the key whose mapping is to be removed from the map.null
if there was no mapping for key. A
null
return can also indicate that the map
previously associated null
with the specified key.java.lang.NullPointerException
- if the key is null
.public FastMap<K,V> shared()
Sets the shared status of this map (whether the map is thread-safe or not). Shared maps are typically used for lookup table (e.g. static instances in ImmortalMemory). They support concurrent access (e.g. iterations) without synchronization, the maps updates themselves are synchronized internally.
Unlike ConcurrentHashMap
access to a shared map never
blocks. Retrieval reflects the map state not older than the last
time the accessing thread has been synchronized (for multi-processors
systems synchronizing ensures that the CPU internal cache is not
stale).
this
@Deprecated public FastMap<K,V> setShared(boolean isShared)
shared()
public boolean isShared()
true
if this map is thread-safe; false
otherwise.public FastMap<K,V> setKeyComparator(FastComparator<? super K> keyComparator)
keyComparator
- the key comparator.this
public FastComparator<? super K> getKeyComparator()
public FastMap<K,V> setValueComparator(FastComparator<? super V> valueComparator)
valueComparator
- the value comparator.this
public FastComparator<? super V> getValueComparator()
public final void clear()
shared
in which case the entries
are candidate for garbage collection.
Note: Shared maps in ImmortalMemory (e.g. static) should not remove
their entries as it could cause a memory leak (ImmortalMemory
is never garbage collected), instead they should set their
entry values to null
.
public boolean equals(java.lang.Object obj)
true
if the given object is also a map and the two
maps represent the same mappings (regardless of collection iteration
order).public int hashCode()
public Text toText()
public final java.lang.String toString()
String
representation of this
FastMap
.toString
in class java.lang.Object
toText().toString()
protected FastMap.Entry<K,V> newEntry()
public void printStatistics(java.io.PrintStream out)
out
- the stream to use for output (e.g. System.out
)public final java.util.Collection<V> values()
FastCollection
view of the values contained in this
map. The collection is backed by the map, so changes to the
map are reflected in the collection, and vice-versa. The collection
supports element removal, which removes the corresponding mapping from
this map, via the Iterator.remove
,
Collection.remove
, removeAll
,
retainAll
and clear
operations.
It does not support the add
or addAll
operations.values
in interface java.util.Map<K,V>
FastCollection
).public final java.util.Set<java.util.Map.Entry<K,V>> entrySet()
FastCollection
view of the mappings contained in this
map. Each element in the returned collection is a
FastMap.Entry
. The collection is backed by the map, so
changes to the map are reflected in the collection, and vice-versa. The
collection supports element removal, which removes the corresponding
mapping from this map, via the Iterator.remove
,
Collection.remove
,removeAll
,
retainAll
, and clear
operations. It does
not support the add
or addAll
operations.entrySet
in interface java.util.Map<K,V>
FastCollection
).public final java.util.Set<K> keySet()
FastCollection
view of the keys contained in this
map. The set is backed by the map, so changes to the map are reflected
in the set, and vice-versa. The set supports element removal, which
removes the corresponding mapping from this map, via the
Iterator.remove
,
Collection.remove
,removeAll,
retainAll
, and clear
operations. It does
not support the add
or addAll
operations.
keySet
in interface java.util.Map<K,V>
FastCollection
).public final java.util.Map<K,V> unmodifiable()
unmodifiable().entrySet()
)
result in an UnsupportedOperationException
being thrown.
Unmodifiable FastCollection
views of this map keys and values
are nonetheless obtainable (e.g. unmodifiable().keySet(),
unmodifiable().values()
).
Copyright © 2005 - 2007 Javolution.