org.cliffc.high_scale_lib
Class NonBlockingHashMapLong<TypeV>

java.lang.Object
  extended by java.util.AbstractMap<Long,TypeV>
      extended by org.cliffc.high_scale_lib.NonBlockingHashMapLong<TypeV>
Type Parameters:
TypeV - the type of mapped values
All Implemented Interfaces:
Serializable, ConcurrentMap<Long,TypeV>, Map<Long,TypeV>

public class NonBlockingHashMapLong<TypeV>
extends AbstractMap<Long,TypeV>
implements ConcurrentMap<Long,TypeV>, Serializable

A lock-free alternate implementation of ConcurrentHashMap with primitive long keys, better scaling properties and generally lower costs. The use of long keys allows for faster compares and lower memory costs. The Map provides identical correctness properties as ConcurrentHashMap. All operations are non-blocking and multi-thread safe, including all update operations. NonBlockingHashMapLong scales substatially better than ConcurrentHashMap for high update rates, even with a large concurrency factor. Scaling is linear up to 768 CPUs on a 768-CPU Azul box, even with 100% updates or 100% reads or any fraction in-between. Linear scaling up to all cpus has been observed on a 32-way Sun US2 box, 32-way Sun Niagra box, 8-way Intel box and a 4-way Power box.

The main benefit of this class over using plain NonBlockingHashMap with NonBlockingHashMapLong.IteratorLong keys is that it avoids the auto-boxing and unboxing costs. Since auto-boxing is automatic, it is easy to accidentally cause auto-boxing and negate the space and speed benefits.

This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable. However, even though all operations are thread-safe, operations do not entail locking and there is not any support for locking the entire table in a way that prevents all access. This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details.

Operations (including put) generally do not block, so may overlap with other update operations (including other puts and removes). Retrievals reflect the results of the most recently completed update operations holding upon their onset. For aggregate operations such as putAll, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.

Very full tables, or tables with high reprobe rates may trigger an internal resize operation to move into a larger table. Resizing is not terribly expensive, but it is not free either; during resize operations table throughput may drop somewhat. All threads that visit the table during a resize will 'help' the resizing but will still be allowed to complete their operation before the resize is finished (i.e., a simple 'get' operation on a million-entry table undergoing resizing will not need to block until the entire million entries are copied).

This class and its views and iterators implement all of the optional methods of the Map and Iterator interfaces.

Like Hashtable but unlike HashMap, this class does not allow null to be used as a value.

Since:
1.5
Author:
Cliff Click
See Also:
Serialized Form

Nested Class Summary
 class NonBlockingHashMapLong.IteratorLong
          A class which implements the Iterator and Enumeration interfaces, generified to the Long class and supporting a non-auto-boxing NonBlockingHashMapLong.IteratorLong.nextLong() function.
 
Nested classes/interfaces inherited from interface java.util.Map
Map.Entry<K,V>
 
Constructor Summary
NonBlockingHashMapLong()
          Create a new NonBlockingHashMapLong with default minimum size (currently set to 8 K/V pairs or roughly 84 bytes on a standard 32-bit JVM).
NonBlockingHashMapLong(boolean opt_for_space)
          Create a new NonBlockingHashMapLong, setting the space-for-speed tradeoff.
NonBlockingHashMapLong(int initial_sz)
          Create a new NonBlockingHashMapLong with initial room for the given number of elements, thus avoiding internal resizing operations to reach an appropriate size.
NonBlockingHashMapLong(int initial_sz, boolean opt_for_space)
          Create a new NonBlockingHashMapLong, setting both the initial size and the space-for-speed tradeoff.
 
Method Summary
 void clear()
          Removes all of the mappings from this map.
 boolean contains(Object val)
          Legacy method testing if some key maps into the specified value in this table.
 boolean containsKey(long key)
          Tests if the key in the table.
 boolean containsKey(Object key)
          Auto-boxing version of containsKey(long).
 boolean containsValue(Object val)
          Returns true if this Map maps one or more keys to the specified value.
 Enumeration<TypeV> elements()
          Returns an enumeration of the values in this table.
 Set<Map.Entry<Long,TypeV>> entrySet()
          Returns a Set view of the mappings contained in this map.
 TypeV get(long key)
          Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
 TypeV get(Object key)
          Auto-boxing version of get(long).
 Enumeration<Long> keys()
          Returns an enumeration of the auto-boxed keys in this table.
 Set<Long> keySet()
          Returns a Set view of the keys contained in this map; with care the keys may be iterated over without auto-boxing.
 void print()
          Verbose printout of table internals, useful for debugging.
 TypeV put(long key, TypeV val)
          Maps the specified key to the specified value in the table.
 TypeV put(Long key, TypeV val)
          Auto-boxing version of put(long, TypeV).
 TypeV putIfAbsent(long key, TypeV val)
          Atomically, do a put(long, TypeV) if-and-only-if the key is not mapped.
 TypeV putIfAbsent(Long key, TypeV val)
          Auto-boxing version of putIfAbsent(long, TypeV).
 TypeV remove(long key)
          Removes the key (and its corresponding value) from this map.
 boolean remove(long key, Object val)
          Atomically do a remove(long) if-and-only-if the key is mapped to a value which is equals to the given value.
 TypeV remove(Object key)
          Auto-boxing version of remove(long).
 boolean remove(Object key, Object Val)
          Auto-boxing version of remove(long,Object).
 TypeV replace(long key, TypeV val)
          Atomically do a put(key,val) if-and-only-if the key is mapped to some value already.
 TypeV replace(Long key, TypeV Val)
          Auto-boxing version of replace(long, TypeV).
 boolean replace(long key, TypeV oldValue, TypeV newValue)
          Atomically do a put(key,newValue) if-and-only-if the key is mapped a value which is equals to oldValue.
 boolean replace(Long key, TypeV oldValue, TypeV newValue)
          Auto-boxing version of replace(long, TypeV).
 long reprobes()
          Get and clear the current count of reprobes.
 int size()
          Returns the number of key-value mappings in this map.
 Collection<TypeV> values()
          Returns a Collection view of the values contained in this map.
 
Methods inherited from class java.util.AbstractMap
equals, hashCode, isEmpty, putAll, toString
 
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.util.Map
equals, hashCode, isEmpty, putAll
 

Constructor Detail

NonBlockingHashMapLong

public NonBlockingHashMapLong()
Create a new NonBlockingHashMapLong with default minimum size (currently set to 8 K/V pairs or roughly 84 bytes on a standard 32-bit JVM).


NonBlockingHashMapLong

public NonBlockingHashMapLong(int initial_sz)
Create a new NonBlockingHashMapLong with initial room for the given number of elements, thus avoiding internal resizing operations to reach an appropriate size. Large numbers here when used with a small count of elements will sacrifice space for a small amount of time gained. The initial size will be rounded up internally to the next larger power of 2.


NonBlockingHashMapLong

public NonBlockingHashMapLong(boolean opt_for_space)
Create a new NonBlockingHashMapLong, setting the space-for-speed tradeoff. true optimizes for space and is the default. false optimizes for speed and doubles space costs for roughly a 10% speed improvement.


NonBlockingHashMapLong

public NonBlockingHashMapLong(int initial_sz,
                              boolean opt_for_space)
Create a new NonBlockingHashMapLong, setting both the initial size and the space-for-speed tradeoff. true optimizes for space and is the default. false optimizes for speed and doubles space costs for roughly a 10% speed improvement.

Method Detail

print

public final void print()
Verbose printout of table internals, useful for debugging.


reprobes

public long reprobes()
Get and clear the current count of reprobes. Reprobes happen on key collisions, and a high reprobe rate may indicate a poor hash function or weaknesses in the table resizing function.

Returns:
the count of reprobes since the last call to reprobes() or since the table was created.

size

public int size()
Returns the number of key-value mappings in this map.

Specified by:
size in interface Map<Long,TypeV>
Overrides:
size in class AbstractMap<Long,TypeV>
Returns:
the number of key-value mappings in this map

containsKey

public boolean containsKey(long key)
Tests if the key in the table.

Returns:
true if the key is in the table

contains

public boolean contains(Object val)
Legacy method testing if some key maps into the specified value in this table. This method is identical in functionality to containsValue(java.lang.Object), and exists solely to ensure full compatibility with class Hashtable, which supported this method prior to introduction of the Java Collections framework.

Parameters:
val - a value to search for
Returns:
true if this map maps one or more keys to the specified value
Throws:
NullPointerException - if the specified value is null

put

public TypeV put(long key,
                 TypeV val)
Maps the specified key to the specified value in the table. The value cannot be null.

The value can be retrieved by calling get(long) with a key that is equal to the original key.

Parameters:
key - key with which the specified value is to be associated
val - value to be associated with the specified key
Returns:
the previous value associated with key, or null if there was no mapping for key
Throws:
NullPointerException - if the specified value is null

putIfAbsent

public TypeV putIfAbsent(long key,
                         TypeV val)
Atomically, do a put(long, TypeV) if-and-only-if the key is not mapped. Useful to ensure that only a single mapping for the key exists, even if many threads are trying to create the mapping in parallel.

Returns:
the previous value associated with the specified key, or null if there was no mapping for the key
Throws:
NullPointerException - if the specified is value is null

remove

public TypeV remove(long key)
Removes the key (and its corresponding value) from this map. This method does nothing if the key is not in the map.

Returns:
the previous value associated with key, or null if there was no mapping for key

remove

public boolean remove(long key,
                      Object val)
Atomically do a remove(long) if-and-only-if the key is mapped to a value which is equals to the given value.

Throws:
NullPointerException - if the specified value is null

replace

public TypeV replace(long key,
                     TypeV val)
Atomically do a put(key,val) if-and-only-if the key is mapped to some value already.

Throws:
NullPointerException - if the specified value is null

replace

public boolean replace(long key,
                       TypeV oldValue,
                       TypeV newValue)
Atomically do a put(key,newValue) if-and-only-if the key is mapped a value which is equals to oldValue.

Throws:
NullPointerException - if the specified value is null

clear

public void clear()
Removes all of the mappings from this map.

Specified by:
clear in interface Map<Long,TypeV>
Overrides:
clear in class AbstractMap<Long,TypeV>

containsValue

public boolean containsValue(Object val)
Returns true if this Map maps one or more keys to the specified value. Note: This method requires a full internal traversal of the hash table and is much slower than containsKey(long).

Specified by:
containsValue in interface Map<Long,TypeV>
Overrides:
containsValue in class AbstractMap<Long,TypeV>
Parameters:
val - value whose presence in this map is to be tested
Returns:
true if this Map maps one or more keys to the specified value
Throws:
NullPointerException - if the specified value is null

get

public final TypeV get(long key)
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

More formally, if this map contains a mapping from a key k to a value v such that key==k, then this method returns v; otherwise it returns null. (There can be at most one such mapping.)

Throws:
NullPointerException - if the specified key is null

get

public TypeV get(Object key)
Auto-boxing version of get(long).

Specified by:
get in interface Map<Long,TypeV>
Overrides:
get in class AbstractMap<Long,TypeV>

remove

public TypeV remove(Object key)
Auto-boxing version of remove(long).

Specified by:
remove in interface Map<Long,TypeV>
Overrides:
remove in class AbstractMap<Long,TypeV>

remove

public boolean remove(Object key,
                      Object Val)
Auto-boxing version of remove(long,Object).

Specified by:
remove in interface ConcurrentMap<Long,TypeV>

containsKey

public boolean containsKey(Object key)
Auto-boxing version of containsKey(long).

Specified by:
containsKey in interface Map<Long,TypeV>
Overrides:
containsKey in class AbstractMap<Long,TypeV>

putIfAbsent

public TypeV putIfAbsent(Long key,
                         TypeV val)
Auto-boxing version of putIfAbsent(long, TypeV).

Specified by:
putIfAbsent in interface ConcurrentMap<Long,TypeV>

replace

public TypeV replace(Long key,
                     TypeV Val)
Auto-boxing version of replace(long, TypeV).

Specified by:
replace in interface ConcurrentMap<Long,TypeV>

put

public TypeV put(Long key,
                 TypeV val)
Auto-boxing version of put(long, TypeV).

Specified by:
put in interface Map<Long,TypeV>
Overrides:
put in class AbstractMap<Long,TypeV>

replace

public boolean replace(Long key,
                       TypeV oldValue,
                       TypeV newValue)
Auto-boxing version of replace(long, TypeV).

Specified by:
replace in interface ConcurrentMap<Long,TypeV>

elements

public Enumeration<TypeV> elements()
Returns an enumeration of the values in this table.

Returns:
an enumeration of the values in this table
See Also:
values()

values

public Collection<TypeV> values()
Returns a Collection 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.

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

Specified by:
values in interface Map<Long,TypeV>
Overrides:
values in class AbstractMap<Long,TypeV>

keys

public Enumeration<Long> keys()
Returns an enumeration of the auto-boxed keys in this table. Warning: this version will auto-box all returned keys.

Returns:
an enumeration of the auto-boxed keys in this table
See Also:
keySet()

keySet

public Set<Long> keySet()
Returns a Set view of the keys contained in this map; with care the keys may be iterated over without auto-boxing. 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, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

Specified by:
keySet in interface Map<Long,TypeV>
Overrides:
keySet in class AbstractMap<Long,TypeV>

entrySet

public Set<Map.Entry<Long,TypeV>> entrySet()
Returns a Set view of the mappings 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 the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException, and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

Warning: the iterator associated with this Set requires the creation of Map.Entry objects with each iteration. The NonBlockingHashMap does not normally create or using Map.Entry objects so they will be created soley to support this iteration. Iterating using keySet() or values() will be more efficient. In addition, this version requires auto-boxing the keys.

Specified by:
entrySet in interface Map<Long,TypeV>
Specified by:
entrySet in class AbstractMap<Long,TypeV>