summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d1111
1 files changed, 0 insertions, 1111 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d b/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d
deleted file mode 100644
index e90087c4..00000000
--- a/debian/uncrustify-trinity/uncrustify-trinity-0.78.1/tests/expected/d/40000-HashMap.d
+++ /dev/null
@@ -1,1111 +0,0 @@
-/*******************************************************************************
-
- @file HashMap.d
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for damages
- of any kind arising from the use of this software.
-
- Permission is hereby granted to anyone to use this software for any
- purpose, including commercial applications, and to alter it and/or
- redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment within documentation of
- said product would be appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 3. This notice may not be removed or altered from any distribution
- of the source.
-
- 4. Derivative works are permitted, but they must carry this notice
- in full and credit the original source.
-
-
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
- Written by Doug Lea with assistance from members of JCP JSR-166
- Expert Group and released to the public domain, as explained at
- http://creativecommons.org/licenses/publicdomain
-
- @version Initial version, July 2004
- @author Doug Lea; ported/modified by Kris
-
-*******************************************************************************/
-
-module mango.cache.HashMap;
-
-/******************************************************************************
-
-******************************************************************************/
-
-extern (C)
-{
-int memcmp(char *, char *, uint);
-}
-
-
-/**
- * A hash table supporting full concurrency of retrievals and
- * adjustable expected concurrency for updates. This class obeys the
- * same functional specification as {@link java.util.Hashtable}, and
- * includes versions of methods corresponding to each method of
- * <tt>Hashtable</tt>. However, even though all operations are
- * thread-safe, retrieval operations do <em>not</em> entail locking,
- * and there is <em>not</em> any support for locking the entire table
- * in a way that prevents all access. This class is fully
- * interoperable with <tt>Hashtable</tt> in programs that rely on its
- * thread safety but not on its synchronization details.
- *
- * <p> Retrieval operations (including <tt>get</tt>) generally do not
- * block, so may overlap with update operations (including
- * <tt>put</tt> and <tt>remove</tt>). Retrievals reflect the results
- * of the most recently <em>completed</em> update operations holding
- * upon their onset. For aggregate operations such as <tt>putAll</tt>
- * and <tt>clear</tt>, 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 <em>not</em> throw
- * {@link ConcurrentModificationException}. However, iterators are
- * designed to be used by only one thread at a time.
- *
- * <p> The allowed concurrency among update operations is guided by
- * the optional <tt>concurrencyLevel</tt> constructor argument
- * (default 16), which is used as a hint for internal sizing. The
- * table is internally partitioned to try to permit the indicated
- * number of concurrent updates without contention. Because placement
- * in hash tables is essentially random, the actual concurrency will
- * vary. Ideally, you should choose a value to accommodate as many
- * threads as will ever concurrently modify the table. Using a
- * significantly higher value than you need can waste space and time,
- * and a significantly lower value can lead to thread contention. But
- * overestimates and underestimates within an order of magnitude do
- * not usually have much noticeable impact. A value of one is
- * appropriate when it is known that only one thread will modify and
- * all others will only read. Also, resizing this or any other kind of
- * hash table is a relatively slow operation, so, when possible, it is
- * a good idea to provide estimates of expected table sizes in
- * constructors.
- *
- * <p>This class and its views and iterators implement all of the
- * <em>optional</em> methods of the {@link Map} and {@link Iterator}
- * interfaces.
- *
- * <p> Like {@link java.util.Hashtable} but unlike {@link
- * java.util.HashMap}, this class does NOT allow <tt>null</tt> to be
- * used as a key or value.
- *
- * <p>This class is a member of the
- * <a href="{@docRoot}/../guide/collections/index.html">
- * Java Collections Framework</a>.
- *
- * @since 1.5
- * @author Doug Lea
- * @param <K> the type of keys maintained by this map
- * @param <V> the type of mapped values
- */
-
-class HashMap
-{
- alias void[] K;
- alias Object V;
- alias jhash hash; // jhash, fnv, or walter
-
- /*
- * The basic strategy is to subdivide the table among Segments,
- * each of which itself is a concurrently readable hash table.
- */
-
- /* ---------------- Constants -------------- */
-
- /**
- * The default initial number of table slots for this table.
- * Used when not otherwise specified in constructor.
- */
- private const uint DEFAULT_INITIAL_CAPACITY = 16;
-
- /**
- * The maximum capacity, used if a higher value is implicitly
- * specified by either of the constructors with arguments. MUST
- * be a power of two <= 1<<30 to ensure that entries are indexible
- * using ints.
- */
- private const uint MAXIMUM_CAPACITY = 1 << 30;
-
- /**
- * The default load factor for this table. Used when not
- * otherwise specified in constructor.
- */
- private const float DEFAULT_LOAD_FACTOR = 0.75f;
-
- /**
- * The default number of concurrency control segments.
- **/
- private const uint DEFAULT_SEGMENTS = 16;
-
- /**
- * The maximum number of segments to allow; used to bound
- * constructor arguments.
- */
- private const uint MAX_SEGMENTS = 1 << 16; // slightly conservative
-
-
- /* ---------------- Fields -------------- */
-
- /**
- * Mask value for indexing into segments. The upper bits of a
- * key's hash code are used to choose the segment.
- **/
- private final int segmentMask;
-
- /**
- * Shift value for indexing within segments.
- **/
- private final int segmentShift;
-
- /**
- * The segments, each of which is a specialized hash table
- */
- private final Segment[] segments;
-
-
- /* ---------------- Small Utilities -------------- */
-
- /**
- * Returns a hash code for non-null Object x.
- * Uses the same hash code spreader as most other java.util hash tables.
- * @param x the object serving as a key
- * @return the hash code
- */
- private static final uint walter(K x)
- {
- uint h = typeid(char[]).getHash(&x);
-
- h += ~(h << 9);
- h ^= (h >>> 14);
- h += (h << 4);
- h ^= (h >>> 10);
- return h;
- }
-
- /**
- * Returns a hash code for non-null Object x.
- * uses the FNV hash function
- * @param x the object serving as a key
- * @return the hash code
- */
- private static final uint fnv(K x)
- {
- uint hash = 2_166_136_261;
-
- foreach (ubyte c; cast(ubyte[])x)
- {
- hash ^= c;
- hash *= 16_777_619;
- }
- return hash;
- }
-
-
-
- /**
- * hash() -- hash a variable-length key into a 32-bit value
- * k : the key (the unaligned variable-length array of bytes)
- * len : the length of the key, counting by bytes
- * level : can be any 4-byte value
- * Returns a 32-bit value. Every bit of the key affects every bit of
- * the return value. Every 1-bit and 2-bit delta achieves avalanche.
- * About 36+6len instructions.
- *
- * The best hash table sizes are powers of 2. There is no need to do
- * mod a prime (mod is sooo slow!). If you need less than 32 bits,
- * use a bitmask. For example, if you need only 10 bits, do
- * h = (h & hashmask(10));
- * In which case, the hash table should have hashsize(10) elements.
- *
- * If you are hashing n strings (ub1 **)k, do it like this:
- * for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
- *
- * By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
- * code any way you wish, private, educational, or commercial. It's free.
- *
- * See http://burlteburtle.net/bob/hash/evahash.html
- * Use for hash table lookup, or anything where one collision in 2^32 is
- * acceptable. Do NOT use for cryptographic purposes.
- */
-
- static final uint jhash(K x)
- {
- ubyte *k;
- uint a,
- b,
- c,
- len;
-
- len = x.length;
- k = cast(ubyte *)x;
- a = b = 0x9e3779b9;
-
- // the previous hash value
- c = 0;
-
- // handle most of the key
- while (len >= 12)
- {
- a += *cast(uint *)(k + 0);
- b += *cast(uint *)(k + 4);
- c += *cast(uint *)(k + 8);
-
- a -= b; a -= c; a ^= (c >> 13);
- b -= c; b -= a; b ^= (a << 8);
- c -= a; c -= b; c ^= (b >> 13);
- a -= b; a -= c; a ^= (c >> 12);
- b -= c; b -= a; b ^= (a << 16);
- c -= a; c -= b; c ^= (b >> 5);
- a -= b; a -= c; a ^= (c >> 3);
- b -= c; b -= a; b ^= (a << 10);
- c -= a; c -= b; c ^= (b >> 15);
- k += 12; len -= 12;
- }
-
- // handle the last 11 bytes
- c += x.length;
- switch (len)
- {
- case 11: c += (cast(uint)k[10] << 24);
-
- case 10: c += (cast(uint)k[9] << 16);
-
- case 9: c += (cast(uint)k[8] << 8);
-
- case 8: b += (cast(uint)k[7] << 24);
-
- case 7: b += (cast(uint)k[6] << 16);
-
- case 6: b += (cast(uint)k[5] << 8);
-
- case 5: b += k[4];
-
- case 4: a += (cast(uint)k[3] << 24);
-
- case 3: a += (cast(uint)k[2] << 16);
-
- case 2: a += (cast(uint)k[1] << 8);
-
- case 1: a += k[0];
-
- default:
- }
-
- a -= b; a -= c; a ^= (c >> 13);
- b -= c; b -= a; b ^= (a << 8);
- c -= a; c -= b; c ^= (b >> 13);
- a -= b; a -= c; a ^= (c >> 12);
- b -= c; b -= a; b ^= (a << 16);
- c -= a; c -= b; c ^= (b >> 5);
- a -= b; a -= c; a ^= (c >> 3);
- b -= c; b -= a; b ^= (a << 10);
- c -= a; c -= b; c ^= (b >> 15);
-
- return c;
- }
-
-
- /**
- * Returns the segment that should be used for key with given hash
- * @param hash the hash code for the key
- * @return the segment
- */
- private final Segment segmentFor(uint hash)
- {
- return segments[(hash >>> segmentShift) & segmentMask];
- }
-
- /* ---------------- Inner Classes -------------- */
-
- /**
- * ConcurrentHashMap list entry. Note that this is never exported
- * out as a user-visible Map.Entry.
- *
- * Because the value field is volatile, not final, it is legal wrt
- * the Java Memory Model for an unsynchronized reader to see null
- * instead of initial value when read via a data race. Although a
- * reordering leading to this is not likely to ever actually
- * occur, the Segment.readValueUnderLock method is used as a
- * backup in case a null (pre-initialized) value is ever seen in
- * an unsynchronized access method.
- */
- private static class HashEntry
- {
- final K key;
- final uint hash;
- final V value;
- final HashEntry next;
-
- this(K key, uint hash, HashEntry next, V value)
- {
- this.key = key;
- this.hash = hash;
- this.next = next;
- this.value = value;
- }
- }
-
- /**
- * Segments are specialized versions of hash tables. This
- * subclasses from ReentrantLock opportunistically, just to
- * simplify some locking and avoid separate construction.
- **/
- static class Segment
- {
- /*
- * Segments maintain a table of entry lists that are ALWAYS
- * kept in a consistent state, so can be read without locking.
- * Next fields of nodes are immutable (final). All list
- * additions are performed at the front of each bin. This
- * makes it easy to check changes, and also fast to traverse.
- * When nodes would otherwise be changed, new nodes are
- * created to replace them. This works well for hash tables
- * since the bin lists tend to be short. (The average length
- * is less than two for the default load factor threshold.)
- *
- * Read operations can thus proceed without locking, but rely
- * on selected uses of volatiles to ensure that completed
- * write operations performed by other threads are
- * noticed. For most purposes, the "count" field, tracking the
- * number of elements, serves as that volatile variable
- * ensuring visibility. This is convenient because this field
- * needs to be read in many read operations anyway:
- *
- * - All (unsynchronized) read operations must first read the
- * "count" field, and should not look at table entries if
- * it is 0.
- *
- * - All (synchronized) write operations should write to
- * the "count" field after structurally changing any bin.
- * The operations must not take any action that could even
- * momentarily cause a concurrent read operation to see
- * inconsistent data. This is made easier by the nature of
- * the read operations in Map. For example, no operation
- * can reveal that the table has grown but the threshold
- * has not yet been updated, so there are no atomicity
- * requirements for this with respect to reads.
- *
- * As a guide, all critical volatile reads and writes to the
- * count field are marked in code comments.
- */
-
- /**
- * The number of elements in this segment's region.
- **/
- int count;
-
- /**
- * The table is rehashed when its size exceeds this threshold.
- * (The value of this field is always (int)(capacity *
- * loadFactor).)
- */
- int threshold;
-
- /**
- * The per-segment table. Declared as a raw type, casted
- * to HashEntry<K,V> on each use.
- */
- HashEntry[] table;
-
- /**
- * The load factor for the hash table. Even though this value
- * is same for all segments, it is replicated to avoid needing
- * links to outer object.
- * @serial
- */
- final float loadFactor;
-
- this(int initialCapacity, float lf)
- {
- loadFactor = lf;
- setTable(new HashEntry[initialCapacity]);
- }
-
- /**
- * Set table to new HashEntry array.
- * Call only while holding lock or in constructor.
- **/
- private final void setTable(HashEntry[] newTable)
- {
- threshold = cast(int)(newTable.length * loadFactor);
- volatile table = newTable;
- }
-
- /**
- * Return properly casted first entry of bin for given hash
- */
- private final HashEntry getFirst(uint hash)
- {
- HashEntry[] tab;
-
- volatile tab = table;
- return tab[hash & (tab.length - 1)];
- }
-
- /**
- * Return true if the two keys match
- */
- private static final bool matchKey(K a, K b)
- {
- if (a.length == b.length)
- return cast(bool)(memcmp(cast(char *)a, cast(char *)b, a.length) == 0);
-
- return false;
- }
-
- /* Specialized implementations of map methods */
-
- final V get(K key, uint hash)
- {
- int c;
-
- // read-volatile
- volatile c = count;
- if (c)
- {
- HashEntry e = getFirst(hash);
-
- while (e)
- {
- if (hash == e.hash && matchKey(key, e.key))
- {
- V v;
-
- volatile v = e.value;
- if (v)
- return v;
-
- synchronized (this)
- return e.value;
- }
- e = e.next;
- }
- }
- return null;
- }
-
-
- final bool containsKey(K key, uint hash)
- {
- int c;
-
- // read-volatile
- volatile c = count;
- if (c)
- {
- HashEntry e = getFirst(hash);
-
- while (e)
- {
- if (e.hash == hash && matchKey(key, e.key))
- return true;
-
- e = e.next;
- }
- }
- return false;
- }
-
-
-
- final synchronized V replace(K key, uint hash, V newValue)
- {
- HashEntry e = getFirst(hash);
-
- while (e && (e.hash != hash || !matchKey(key, e.key)))
- e = e.next;
-
- V oldValue = null;
-
- if (e)
- volatile
- {
- oldValue = e.value;
- e.value = newValue;
- }
- return oldValue;
- }
-
-
- final synchronized V put(K key, uint hash, V value, bool onlyIfAbsent)
- {
- int c;
-
- volatile c = count;
- if (c++ > threshold)
- rehash();
-
- HashEntry[] tab;
-
- volatile tab = table;
- uint index = hash & (tab.length - 1);
- HashEntry first = tab[index];
- HashEntry e = first;
-
- while (e && (e.hash != hash || !matchKey(key, e.key)))
- e = e.next;
-
- V oldValue;
-
- if (e)
- {
- volatile oldValue = e.value;
- if (!onlyIfAbsent)
- volatile e.value = value;
- }
- else
- {
- oldValue = null;
- tab[index] = new HashEntry(key, hash, first, value);
-
- // write-volatile
- volatile count = c;
- }
- return oldValue;
- }
-
-
- private final void rehash()
- {
- HashEntry[] oldTable;
-
- volatile oldTable = table;
- int oldCapacity = oldTable.length;
-
- if (oldCapacity >= MAXIMUM_CAPACITY)
- return;
-
- /*
- * Reclassify nodes in each list to new Map. Because we are
- * using power-of-two expansion, the elements from each bin
- * must either stay at same index, or move with a power of two
- * offset. We eliminate unnecessary node creation by catching
- * cases where old nodes can be reused because their next
- * fields won't change. Statistically, at the default
- * threshold, only about one-sixth of them need cloning when
- * a table doubles. The nodes they replace will be garbage
- * collectable as soon as they are no longer referenced by any
- * reader thread that may be in the midst of traversing table
- * right now.
- */
-
- HashEntry[] newTable = new HashEntry[oldCapacity << 1];
-
- threshold = cast(int)(newTable.length * loadFactor);
- int sizeMask = newTable.length - 1;
-
- for (int i = 0; i < oldCapacity; ++i)
- {
- // We need to guarantee that any existing reads of old Map can
- // proceed. So we cannot yet null out each bin.
- HashEntry e = oldTable[i];
-
- if (e)
- {
- HashEntry next = e.next;
- uint idx = e.hash & sizeMask;
-
- // Single node on list
- if (next is null)
- newTable[idx] = e;
- else
- {
- // Reuse trailing consecutive sequence at same slot
- HashEntry lastRun = e;
- int lastIdx = idx;
-
- for (HashEntry last = next; last; last = last.next)
- {
- uint k = last.hash & sizeMask;
-
- if (k != lastIdx)
- {
- lastIdx = k;
- lastRun = last;
- }
- }
- newTable[lastIdx] = lastRun;
-
- // Clone all remaining nodes
- for (HashEntry p = e; p !is lastRun; p = p.next)
- {
- uint k = p.hash & sizeMask;
- HashEntry n = newTable[k];
-
- newTable[k] = new HashEntry(p.key, p.hash, n, p.value);
- }
- }
- }
- }
- volatile table = newTable;
- }
-
- /**
- * Remove; match on key only if value null, else match both.
- */
- final synchronized V remove(K key, uint hash, V value)
- {
- int c;
- HashEntry[] tab;
-
- volatile c = count - 1;
- volatile tab = table;
-
- uint index = hash & (tab.length - 1);
- HashEntry first = tab[index];
- HashEntry e = first;
-
- while (e && (e.hash != hash || !matchKey(key, e.key)))
- e = e.next;
-
- V oldValue = null;
-
- if (e)
- {
- V v;
-
- volatile v = e.value;
- if (value is null || value == v)
- {
- oldValue = v;
-
- // All entries following removed node can stay
- // in list, but all preceding ones need to be
- // cloned.
- HashEntry newFirst = e.next;
-
- for (HashEntry p = first; p !is e; p = p.next)
- newFirst = new HashEntry(p.key, p.hash, newFirst, p.value);
- tab[index] = newFirst;
-
- // write-volatile
- volatile count = c;
- }
- }
- return oldValue;
- }
-
-
- final synchronized void clear()
- {
- if (count)
- {
- HashEntry[] tab;
-
- volatile tab = table;
-
- for (int i = 0; i < tab.length; i++)
- tab[i] = null;
-
- // write-volatile
- volatile count = 0;
- }
- }
- }
-
-
-
- /* ---------------- Public operations -------------- */
-
- /**
- * Creates a new, empty map with the specified initial
- * capacity and the specified load factor.
- *
- * @param initialCapacity the initial capacity. The implementation
- * performs internal sizing to accommodate this many elements.
- * @param loadFactor the load factor threshold, used to control resizing.
- * @param concurrencyLevel the estimated number of concurrently
- * updating threads. The implementation performs internal sizing
- * to try to accommodate this many threads.
- * @throws IllegalArgumentException if the initial capacity is
- * negative or the load factor or concurrencyLevel are
- * nonpositive.
- */
- public this(uint initialCapacity, float loadFactor, uint concurrencyLevel)
- {
- assert(loadFactor > 0);
-
- if (concurrencyLevel > MAX_SEGMENTS)
- concurrencyLevel = MAX_SEGMENTS;
-
- // Find power-of-two sizes best matching arguments
- int sshift = 0;
- int ssize = 1;
-
- while (ssize < concurrencyLevel)
- {
- ++sshift;
- ssize <<= 1;
- }
-
- segmentShift = 32 - sshift;
- segmentMask = ssize - 1;
- this.segments = new Segment[ssize];
-
- if (initialCapacity > MAXIMUM_CAPACITY)
- initialCapacity = MAXIMUM_CAPACITY;
-
- int c = initialCapacity / ssize;
-
- if (c * ssize < initialCapacity)
- ++c;
-
- int cap = 1;
-
- while (cap < c)
- cap <<= 1;
-
- for (int i = 0; i < this.segments.length; ++i)
- this.segments[i] = new Segment(cap, loadFactor);
- }
-
- /**
- * Creates a new, empty map with the specified initial
- * capacity, and with default load factor and concurrencyLevel.
- *
- * @param initialCapacity The implementation performs internal
- * sizing to accommodate this many elements.
- * @throws IllegalArgumentException if the initial capacity of
- * elements is negative.
- */
- public this(uint initialCapacity)
- {
- this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
- }
-
- /**
- * Creates a new, empty map with a default initial capacity,
- * load factor, and concurrencyLevel.
- */
- public this()
- {
- this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_SEGMENTS);
- }
-
- /**
- * Returns the value to which the specified key is mapped in this table.
- *
- * @param key a key in the table.
- * @return the value to which the key is mapped in this table;
- * <tt>null</tt> if the key is not mapped to any value in
- * this table.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
- */
- public V get(K key)
- {
- uint hash = hash(key); // throws NullPointerException if key null
-
- return segmentFor(hash).get(key, hash);
- }
-
- /**
- * Tests if the specified object is a key in this table.
- *
- * @param key possible key.
- * @return <tt>true</tt> if and only if the specified object
- * is a key in this table, as determined by the
- * <tt>equals</tt> method; <tt>false</tt> otherwise.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
- */
- public bool containsKey(K key)
- {
- uint hash = hash(key); // throws NullPointerException if key null
-
- return segmentFor(hash).containsKey(key, hash);
- }
-
- /**
- * Maps the specified <tt>key</tt> to the specified
- * <tt>value</tt> in this table. Neither the key nor the
- * value can be <tt>null</tt>.
- *
- * <p> The value can be retrieved by calling the <tt>get</tt> method
- * with a key that is equal to the original key.
- *
- * @param key the table key.
- * @param value the value.
- * @return the previous value of the specified key in this table,
- * or <tt>null</tt> if it did not have one.
- * @throws NullPointerException if the key or value is
- * <tt>null</tt>.
- */
- public V put(K key, V value)
- {
- assert(value);
-
- uint hash = hash(key);
-
- return segmentFor(hash).put(key, hash, value, false);
- }
-
- /**
- * If the specified key is not already associated
- * with a value, associate it with the given value.
- * This is equivalent to
- * <pre>
- * if (!map.containsKey(key))
- * return map.put(key, value);
- * else
- * return map.get(key);
- * </pre>
- * Except that the action is performed atomically.
- * @param key key with which the specified value is to be associated.
- * @param value value to be associated with the specified key.
- * @return previous value associated with specified key, or <tt>null</tt>
- * if there was no mapping for key.
- * @throws NullPointerException if the specified key or value is
- * <tt>null</tt>.
- */
- public V putIfAbsent(K key, V value)
- {
- assert(value);
-
- uint hash = hash(key);
-
- return segmentFor(hash).put(key, hash, value, true);
- }
-
-
- /**
- * Removes the key (and its corresponding value) from this
- * table. This method does nothing if the key is not in the table.
- *
- * @param key the key that needs to be removed.
- * @return the value to which the key had been mapped in this table,
- * or <tt>null</tt> if the key did not have a mapping.
- * @throws NullPointerException if the key is
- * <tt>null</tt>.
- */
- public V remove(K key)
- {
- uint hash = hash(key);
-
- return segmentFor(hash).remove(key, hash, null);
- }
-
- /**
- * Remove entry for key only if currently mapped to given value.
- * Acts as
- * <pre>
- * if (map.get(key).equals(value)) {
- * map.remove(key);
- * return true;
- * } else return false;
- * </pre>
- * except that the action is performed atomically.
- * @param key key with which the specified value is associated.
- * @param value value associated with the specified key.
- * @return true if the value was removed
- * @throws NullPointerException if the specified key is
- * <tt>null</tt>.
- */
- public bool remove(K key, V value)
- {
- uint hash = hash(key);
-
- return cast(bool)(segmentFor(hash).remove(key, hash, value) !is null);
- }
-
-
- /**
- * Replace entry for key only if currently mapped to some value.
- * Acts as
- * <pre>
- * if ((map.containsKey(key)) {
- * return map.put(key, value);
- * } else return null;
- * </pre>
- * except that the action is performed atomically.
- * @param key key with which the specified value is associated.
- * @param value value to be associated with the specified key.
- * @return previous value associated with specified key, or <tt>null</tt>
- * if there was no mapping for key.
- * @throws NullPointerException if the specified key or value is
- * <tt>null</tt>.
- */
- public V replace(K key, V value)
- {
- assert(value);
-
- uint hash = hash(key);
-
- return segmentFor(hash).replace(key, hash, value);
- }
-
-
- /**
- * Removes all mappings from this map.
- */
- public void clear()
- {
- for (int i = 0; i < segments.length; ++i)
- segments[i].clear();
- }
-
-
- /**
- * Returns an enumeration of the keys in this table.
- *
- * @return an enumeration of the keys in this table.
- * @see #keySet
- */
- public KeyIterator keys()
- {
- return new KeyIterator(this);
- }
-
- /**
- * Returns an enumeration of the values in this table.
- *
- * @return an enumeration of the values in this table.
- * @see #values
- */
- public ValueIterator elements()
- {
- return new ValueIterator(this);
- }
-
- /**********************************************************************
-
- Iterate over all keys in hashmap
-
- **********************************************************************/
-
- int opApply(int delegate(inout char[]) dg)
- {
- int result = 0;
- KeyIterator iterator = keys();
-
- while (iterator.hasNext)
- {
- char[] ca = cast(char[])iterator.next;
-
- if ((result = dg(ca)) != 0)
- break;
- }
- return result;
- }
-
- /**********************************************************************
-
- Iterate over all keys in hashmap
-
- **********************************************************************/
-
- int opApply(int delegate(inout char[], inout Object) dg)
- {
- int result = 0;
- KeyIterator iterator = keys();
-
- while (iterator.hasNext)
- {
- HashEntry he = iterator.nextElement;
- char[] ca = cast(char[])he.key;
-
- if ((result = dg(ca, he.value)) != 0)
- break;
- }
- return result;
- }
-
-
- /* ---------------- Iterator Support -------------- */
-
- abstract static class HashIterator
- {
- int nextSegmentIndex;
- int nextTableIndex;
- HashEntry[] currentTable;
- HashEntry nextEntry;
- HashEntry lastReturned;
- HashMap map;
-
- this(HashMap map)
- {
- this.map = map;
- nextSegmentIndex = map.segments.length - 1;
- nextTableIndex = -1;
- advance();
- }
-
- final void advance()
- {
- if (nextEntry !is null && (nextEntry = nextEntry.next) !is null)
- return;
-
- while (nextTableIndex >= 0)
- {
- if ((nextEntry = currentTable[nextTableIndex--]) !is null)
- return;
- }
-
- while (nextSegmentIndex >= 0)
- {
- Segment seg = map.segments[nextSegmentIndex--];
-
- volatile if (seg.count)
- {
- currentTable = seg.table;
- for (int j = currentTable.length - 1; j >= 0; --j)
- {
- if ((nextEntry = currentTable[j]) !is null)
- {
- nextTableIndex = j - 1;
- return;
- }
- }
- }
- }
- }
-
- public bool hasNext()
- {
- return cast(bool)(nextEntry !is null);
- }
-
- HashEntry nextElement()
- {
- if (nextEntry is null)
- throw new Exception("no such element in HashMap");
-
- lastReturned = nextEntry;
- advance();
- return lastReturned;
- }
- }
-
- static class KeyIterator : HashIterator
- {
- this(HashMap map) {
- super(map);
- }
- public K next()
- {
- return super.nextElement().key;
- }
- }
-
- static class ValueIterator : HashIterator
- {
- this(HashMap map) {
- super(map);
- }
- public V next()
- {
- volatile return super.nextElement().value;
- }
- }
-}