Delete unneeded interface dependencies of HashPMap
To reduce class count and to avoid unneeded invokeinterface's
This commit is contained in:
@@ -11,7 +11,7 @@ import java.util.NoSuchElementException;
|
||||
*
|
||||
* @author harold
|
||||
*/
|
||||
public final class ConsPStack<E> implements PStack<E> {
|
||||
public final class ConsPStack<E> implements Iterable<E> {
|
||||
private static final ConsPStack<Object> EMPTY = new ConsPStack<Object>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -48,7 +48,6 @@ public final class ConsPStack<E> implements PStack<E> {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
@@ -111,7 +110,6 @@ public final class ConsPStack<E> implements PStack<E> {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsPStack<E> plus(E e) {
|
||||
return new ConsPStack<E>(e, this);
|
||||
}
|
||||
@@ -126,7 +124,6 @@ public final class ConsPStack<E> implements PStack<E> {
|
||||
return new ConsPStack<E>(first, newRest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConsPStack<E> minus(int i) {
|
||||
return minus(get(i));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package kotlin.reflect.jvm.internal.pcollections;
|
||||
|
||||
import static java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* A persistent map from non-null keys to non-null values.
|
||||
* <p/>
|
||||
@@ -13,18 +11,18 @@ import static java.util.Map.Entry;
|
||||
*
|
||||
* @author harold
|
||||
*/
|
||||
public final class HashPMap<K, V> implements PMap<K, V> {
|
||||
public static final HashPMap<Object, Object> EMPTY = new HashPMap<Object, Object>(IntTreePMap.<PStack<Entry<Object, Object>>>empty(), 0);
|
||||
public final class HashPMap<K, V> {
|
||||
private static final HashPMap<Object, Object> EMPTY = new HashPMap<Object, Object>(IntTreePMap.<ConsPStack<MapEntry<Object, Object>>>empty(), 0);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <K, V> HashPMap<K, V> empty() {
|
||||
return (HashPMap<K, V>) HashPMap.EMPTY;
|
||||
}
|
||||
|
||||
private final IntTreePMap<PStack<Entry<K, V>>> intMap;
|
||||
private final IntTreePMap<ConsPStack<MapEntry<K, V>>> intMap;
|
||||
private final int size;
|
||||
|
||||
private HashPMap(IntTreePMap<PStack<Entry<K, V>>> intMap, int size) {
|
||||
private HashPMap(IntTreePMap<ConsPStack<MapEntry<K, V>>> intMap, int size) {
|
||||
this.intMap = intMap;
|
||||
this.size = size;
|
||||
}
|
||||
@@ -37,28 +35,25 @@ public final class HashPMap<K, V> implements PMap<K, V> {
|
||||
return keyIndexIn(getEntries(key.hashCode()), key) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object key) {
|
||||
PStack<Entry<K, V>> entries = getEntries(key.hashCode());
|
||||
for (Entry<K, V> entry : entries)
|
||||
ConsPStack<MapEntry<K, V>> entries = getEntries(key.hashCode());
|
||||
for (MapEntry<K, V> entry : entries)
|
||||
if (entry.getKey().equals(key))
|
||||
return entry.getValue();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashPMap<K, V> plus(K key, V value) {
|
||||
PStack<Entry<K, V>> entries = getEntries(key.hashCode());
|
||||
ConsPStack<MapEntry<K, V>> entries = getEntries(key.hashCode());
|
||||
int size0 = entries.size();
|
||||
int i = keyIndexIn(entries, key);
|
||||
if (i != -1) entries = entries.minus(i);
|
||||
entries = entries.plus(new SimpleImmutableEntry<K, V>(key, value));
|
||||
entries = entries.plus(new MapEntry<K, V>(key, value));
|
||||
return new HashPMap<K, V>(intMap.plus(key.hashCode(), entries), size - size0 + entries.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashPMap<K, V> minus(Object key) {
|
||||
PStack<Entry<K, V>> entries = getEntries(key.hashCode());
|
||||
ConsPStack<MapEntry<K, V>> entries = getEntries(key.hashCode());
|
||||
int i = keyIndexIn(entries, key);
|
||||
if (i == -1) // key not in this
|
||||
return this;
|
||||
@@ -69,15 +64,15 @@ public final class HashPMap<K, V> implements PMap<K, V> {
|
||||
return new HashPMap<K, V>(intMap.plus(key.hashCode(), entries), size - 1);
|
||||
}
|
||||
|
||||
private PStack<Entry<K, V>> getEntries(int hash) {
|
||||
PStack<Entry<K, V>> entries = intMap.get(hash);
|
||||
private ConsPStack<MapEntry<K, V>> getEntries(int hash) {
|
||||
ConsPStack<MapEntry<K, V>> entries = intMap.get(hash);
|
||||
if (entries == null) return ConsPStack.empty();
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static <K, V> int keyIndexIn(PStack<Entry<K, V>> entries, Object key) {
|
||||
private static <K, V> int keyIndexIn(ConsPStack<MapEntry<K, V>> entries, Object key) {
|
||||
int i = 0;
|
||||
for (Entry<K, V> entry : entries) {
|
||||
for (MapEntry<K, V> entry : entries) {
|
||||
if (entry.getKey().equals(key))
|
||||
return i;
|
||||
i++;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package kotlin.reflect.jvm.internal.pcollections;
|
||||
|
||||
/**
|
||||
* <p/>
|
||||
* An Entry maintaining an immutable key and value. This class
|
||||
* does not support method <tt>setValue</tt>. This class may be
|
||||
* convenient in methods that return thread-safe snapshots of
|
||||
* key-value mappings.
|
||||
*/
|
||||
final class MapEntry<K, V> implements java.io.Serializable {
|
||||
private static final long serialVersionUID = 7138329143949025153L;
|
||||
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
public MapEntry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof MapEntry)) return false;
|
||||
MapEntry<?, ?> e = (MapEntry<?, ?>) o;
|
||||
return (key == null ? e.key == null : key.equals(e.key)) &&
|
||||
(value == null ? e.value == null : value.equals(e.value));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (key == null ? 0 : key.hashCode()) ^
|
||||
(value == null ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package kotlin.reflect.jvm.internal.pcollections;
|
||||
|
||||
/**
|
||||
* An immutable, persistent map from non-null keys of type K to non-null values of type V.
|
||||
*
|
||||
* @author harold
|
||||
*/
|
||||
public interface PMap<K, V> {
|
||||
public PMap<K, V> plus(K key, V value);
|
||||
|
||||
public PMap<K, V> minus(Object key);
|
||||
|
||||
V get(Object key);
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package kotlin.reflect.jvm.internal.pcollections;
|
||||
|
||||
/**
|
||||
* An immutable, persistent stack.
|
||||
*
|
||||
* @author harold
|
||||
*/
|
||||
public interface PStack<E> extends Iterable<E> {
|
||||
PStack<E> plus(E e);
|
||||
|
||||
PStack<E> minus(int i);
|
||||
|
||||
int size();
|
||||
}
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
package kotlin.reflect.jvm.internal.pcollections;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p/>
|
||||
* An Entry maintaining an immutable key and value. This class
|
||||
* does not support method <tt>setValue</tt>. This class may be
|
||||
* convenient in methods that return thread-safe snapshots of
|
||||
* key-value mappings.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
final class SimpleImmutableEntry<K, V> implements Map.Entry<K, V>, java.io.Serializable {
|
||||
private static final long serialVersionUID = 7138329143949025153L;
|
||||
|
||||
private final K key;
|
||||
private final V value;
|
||||
|
||||
/**
|
||||
* Creates an entry representing a mapping from the specified
|
||||
* key to the specified value.
|
||||
*
|
||||
* @param key the key represented by this entry
|
||||
* @param value the value represented by this entry
|
||||
*/
|
||||
public SimpleImmutableEntry(K key, V value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key corresponding to this entry.
|
||||
*
|
||||
* @return the key corresponding to this entry
|
||||
*/
|
||||
@Override
|
||||
public K getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value corresponding to this entry.
|
||||
*
|
||||
* @return the value corresponding to this entry
|
||||
*/
|
||||
@Override
|
||||
public V getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the value corresponding to this entry with the specified
|
||||
* value (optional operation). This implementation simply throws
|
||||
* <tt>UnsupportedOperationException</tt>, as this class implements
|
||||
* an <i>immutable</i> map entry.
|
||||
*
|
||||
* @param value new value to be stored in this entry
|
||||
* @return (Does not return)
|
||||
* @throws UnsupportedOperationException always
|
||||
*/
|
||||
@Override
|
||||
public V setValue(V value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified object with this entry for equality.
|
||||
* Returns {@code true} if the given object is also a map entry and
|
||||
* the two entries represent the same mapping. More formally, two
|
||||
* entries {@code e1} and {@code e2} represent the same mapping
|
||||
* if<pre>
|
||||
* (e1.getKey()==null ?
|
||||
* e2.getKey()==null :
|
||||
* e1.getKey().equals(e2.getKey()))
|
||||
* &&
|
||||
* (e1.getValue()==null ?
|
||||
* e2.getValue()==null :
|
||||
* e1.getValue().equals(e2.getValue()))</pre>
|
||||
* This ensures that the {@code equals} method works properly across
|
||||
* different implementations of the {@code Map.Entry} interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this map entry
|
||||
* @return {@code true} if the specified object is equal to this map
|
||||
* entry
|
||||
* @see #hashCode
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
|
||||
return eq(key, e.getKey()) && eq(value, e.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this map entry. The hash code
|
||||
* of a map entry {@code e} is defined to be: <pre>
|
||||
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
|
||||
* (e.getValue()==null ? 0 : e.getValue().hashCode())</pre>
|
||||
* This ensures that {@code e1.equals(e2)} implies that
|
||||
* {@code e1.hashCode()==e2.hashCode()} for any two Entries
|
||||
* {@code e1} and {@code e2}, as required by the general
|
||||
* contract of {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this map entry
|
||||
* @see #equals
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (key == null ? 0 : key.hashCode()) ^
|
||||
(value == null ? 0 : value.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this map entry. This
|
||||
* implementation returns the string representation of this
|
||||
* entry's key followed by the equals character ("<tt>=</tt>")
|
||||
* followed by the string representation of this entry's value.
|
||||
*
|
||||
* @return a String representation of this map entry
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for SimpleEntry and SimpleImmutableEntry.
|
||||
* Test for equality, checking for nulls.
|
||||
*/
|
||||
private static boolean eq(Object o1, Object o2) {
|
||||
return o1 == null ? o2 == null : o1.equals(o2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user