@Override InnerNode<K, V> remove(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return this; final int slot = slot(hash6); final Object previousValue = subNodes[slot]; if (previousValue instanceof Node) { return removeSlot(hash6, slot); return new InnerNode<>(mask, keys2, subNodes2); } else if (keys[slot].equals(key)) { return removeSlot(hash6, slot); } else {
@Override public V get(Object key) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } final int hash = key.hashCode(); return root.get(key, hash); }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
@Override InnerNode<K, V> remove(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return this; final int slot = slot(hash6); final Object previousValue = subNodes[slot]; if (previousValue instanceof Node) { return removeSlot(hash6, slot); return new InnerNode<>(mask, keys2, subNodes2); } else if (keys[slot].equals(key)) { return removeSlot(hash6, slot); } else {
@Override InnerNode<K, V> remove(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return this; final int slot = slot(hash6); final Object previousValue = subNodes[slot]; if (previousValue instanceof Node) { return removeSlot(hash6, slot); return new InnerNode<>(mask, keys2, subNodes2); } else if (keys[slot].equals(key)) { return removeSlot(hash6, slot); } else {
@Override V get(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return null; } final int slot = slot(hash6); final Object sub = subNodes[slot]; assert sub != null; if (sub instanceof Node) { assert keys[slot] == null; // keys don't make sense on inner nodes @SuppressWarnings("unchecked") final Node<K, V> subNode = (Node<K, V>) sub; return subNode.get(key, hash >>> HASH_BITS); } else { if (keys[slot].equals(key)) { @SuppressWarnings("unchecked") final V v = (V) sub; return v; } else { // we have an entry for this hash, but the value is different return null; } } }
@Override InnerNode<K, V> remove(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return this; final int slot = slot(hash6); final Object previousValue = subNodes[slot]; if (previousValue instanceof Node) { return removeSlot(hash6, slot); return new InnerNode<>(mask, keys2, subNodes2); } else if (keys[slot].equals(key)) { return removeSlot(hash6, slot); } else {
@Override InnerNode<K, V> remove(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return this; final int slot = slot(hash6); final Object previousValue = subNodes[slot]; if (previousValue instanceof Node) { return removeSlot(hash6, slot); return new InnerNode<>(mask, keys2, subNodes2); } else if (keys[slot].equals(key)) { return removeSlot(hash6, slot); } else {
@Override V get(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return null; } final int slot = slot(hash6); final Object sub = subNodes[slot]; assert sub != null; if (sub instanceof Node) { assert keys[slot] == null; // keys don't make sense on inner nodes @SuppressWarnings("unchecked") final Node<K, V> subNode = (Node<K, V>) sub; return subNode.get(key, hash >>> HASH_BITS); } else { if (keys[slot].equals(key)) { @SuppressWarnings("unchecked") final V v = (V) sub; return v; } else { // we have an entry for this hash, but the value is different return null; } } }
@Override V get(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return null; } final int slot = slot(hash6); final Object sub = subNodes[slot]; assert sub != null; if (sub instanceof Node) { assert keys[slot] == null; // keys don't make sense on inner nodes @SuppressWarnings("unchecked") final Node<K, V> subNode = (Node<K, V>) sub; return subNode.get(key, hash >>> HASH_BITS); } else { if (keys[slot].equals(key)) { @SuppressWarnings("unchecked") final V v = (V) sub; return v; } else { // we have an entry for this hash, but the value is different return null; } } }
@Override V get(Object key, int hash) { final int hash6 = hash & HASH_MASK; if (!exists(hash6)) { return null; } final int slot = slot(hash6); final Object sub = subNodes[slot]; assert sub != null; if (sub instanceof Node) { assert keys[slot] == null; // keys don't make sense on inner nodes @SuppressWarnings("unchecked") final Node<K, V> subNode = (Node<K, V>) sub; return subNode.get(key, hash >>> HASH_BITS); } else { if (keys[slot].equals(key)) { @SuppressWarnings("unchecked") final V v = (V) sub; return v; } else { // we have an entry for this hash, but the value is different return null; } } }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
private InnerNode<K, V> putExisting(K key, int hash, int hashBits, int slot, V value, MutableValueInt newValue) { final K[] keys2 = Arrays.copyOf(keys, keys.length); final Object[] subNodes2 = Arrays.copyOf(subNodes, subNodes.length); final Object previousValue = subNodes2[slot]; if (previousValue instanceof Node) { // insert recursively assert keys[slot] == null; subNodes2[slot] = ((Node<K, V>) previousValue).put(key, hash, hashBits, value, newValue); } else if (keys[slot].equals(key)) { // replace the existing entry subNodes2[slot] = value; } else { // hash collision final K previousKey = keys[slot]; final int previousHash = previousKey.hashCode() >>> (TOTAL_HASH_BITS - hashBits); Node<K, V> subNode = newSubNode(hashBits); subNode = subNode.put(previousKey, previousHash, hashBits, (V) previousValue, newValue); subNode = subNode.put(key, hash, hashBits, value, newValue); keys2[slot] = null; subNodes2[slot] = subNode; } return new InnerNode<>(mask, keys2, subNodes2); }
/** * Associate <code>key</code> with <code>value</code> and return a new copy * of the hash table. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndPut(K key, V value) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } if (value == null) { throw new IllegalArgumentException("null values are not supported"); } final int hash = key.hashCode(); final MutableValueInt newValue = new MutableValueInt(); final InnerNode<K, V> newRoot = root.put(key, hash, TOTAL_HASH_BITS, value, newValue); final int newSize = size + newValue.value; return new CopyOnWriteHashMap<>(newRoot, newSize); }
/** * Associate <code>key</code> with <code>value</code> and return a new copy * of the hash table. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndPut(K key, V value) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } if (value == null) { throw new IllegalArgumentException("null values are not supported"); } final int hash = key.hashCode(); final MutableValueInt newValue = new MutableValueInt(); final InnerNode<K, V> newRoot = root.put(key, hash, TOTAL_HASH_BITS, value, newValue); final int newSize = size + newValue.value; return new CopyOnWriteHashMap<>(newRoot, newSize); }
/** * Remove the given key from this map. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndRemove(Object key) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } final int hash = key.hashCode(); final InnerNode<K, V> newRoot = root.remove(key, hash); if (root == newRoot) { return this; } else { return new CopyOnWriteHashMap<>(newRoot, size - 1); } }
/** * Associate <code>key</code> with <code>value</code> and return a new copy * of the hash table. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndPut(K key, V value) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } if (value == null) { throw new IllegalArgumentException("null values are not supported"); } final int hash = key.hashCode(); final MutableValueInt newValue = new MutableValueInt(); final InnerNode<K, V> newRoot = root.put(key, hash, TOTAL_HASH_BITS, value, newValue); final int newSize = size + newValue.value; return new CopyOnWriteHashMap<>(newRoot, newSize); }
/** * Remove the given key from this map. The current hash table is not modified. */ public CopyOnWriteHashMap<K, V> copyAndRemove(Object key) { if (key == null) { throw new IllegalArgumentException("null keys are not supported"); } final int hash = key.hashCode(); final InnerNode<K, V> newRoot = root.remove(key, hash); if (root == newRoot) { return this; } else { return new CopyOnWriteHashMap<>(newRoot, size - 1); } }