package org.radargun.utils;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map optimized for holding single or none entry, but allowing more entries
* by delegating the operations to inner map.
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class OptimizedMap<K, V> implements Map<K, V>, Serializable {
private enum Type {
EMPTY,
SINGLE,
MAP
}
private Type type = Type.EMPTY;
private Map<K, V> inner;
private K singleKey;
private V singleValue;
@Override
public int size() {
return singleValue == null && inner == null ? 0 : (inner == null ? 1 : inner.size());
}
@Override
public boolean isEmpty() {
return type == Type.EMPTY || size() == 0;
}
@Override
public boolean containsKey(Object key) {
switch (type) {
case EMPTY:
return false;
case SINGLE:
return key == null ? singleKey == null : key.equals(singleKey);
case MAP:
return inner.containsKey(key);
}
throw new IllegalStateException();
}
@Override
public boolean containsValue(Object value) {
switch (type) {
case EMPTY:
return false;
case SINGLE:
return value == null ? singleValue == null : value.equals(singleKey);
case MAP:
return inner.containsValue(value);
}
throw new IllegalStateException();
}
@Override
public V get(Object key) {
switch (type) {
case EMPTY:
return null;
case SINGLE:
return key == null ? (singleKey == null ? singleValue : null)
: (key.equals(singleKey) ? singleValue : null);
case MAP:
return inner.get(key);
}
throw new IllegalStateException();
}
@Override
public V put(K key, V value) {
switch (type) {
case EMPTY:
singleKey = key;
singleValue = value;
type = Type.SINGLE;
return null;
case SINGLE:
if (key == null) {
if (singleKey == null) {
return replaceValue(value);
} else {
return switchToMap(key, value);
}
} else if (key.equals(singleKey)) {
return replaceValue(value);
} else {
return switchToMap(key, value);
}
case MAP:
return inner.put(key, value);
}
throw new IllegalStateException();
}
private V replaceValue(V value) {
V temp = singleValue;
singleValue = value;
return temp;
}
private V switchToMap(K key, V value) {
inner = new HashMap<K, V>();
inner.put(singleKey, singleValue);
type = Type.MAP;
return inner.put(key, value);
}
@Override
public V remove(Object key) {
// TODO
throw new UnsupportedOperationException();
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
// TODO
throw new UnsupportedOperationException();
}
@Override
public void clear() {
type = Type.EMPTY;
}
@Override
public Set<K> keySet() {
// TODO backing the set is non-trivial
throw new UnsupportedOperationException();
}
@Override
public Collection<V> values() {
// TODO backing the set is non-trivial
throw new UnsupportedOperationException();
}
@Override
public Set<Entry<K, V>> entrySet() {
// TODO backing the set is non-trivial
throw new UnsupportedOperationException();
}
}