org.mvel2.util.SimpleIndexHashMapWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of virtdata-lib-realer Show documentation
Show all versions of virtdata-lib-realer Show documentation
With inspiration from other libraries
package org.mvel2.util;
import java.util.*;
/**
* As most use-cases of the VariableResolverFactory's rely on Maps, this is meant to implement a simple wrapper
* which records index positions for use by the optimizing facilities.
*
* This wrapper also ensures that the Map is only additive. You cannot remove an element once it's been added.
* While this may seem like an odd limitation, it is consistent with the language semantics. (ie. it's not possible
* to delete a variable at runtime once it's been declared).
*
* @author Mike Brock
*/
public class SimpleIndexHashMapWrapper implements Map {
private int indexCounter;
private final Map> wrappedMap;
private final ArrayList> indexBasedLookup;
public SimpleIndexHashMapWrapper() {
this.wrappedMap = new HashMap>();
this.indexBasedLookup = new ArrayList>();
}
public SimpleIndexHashMapWrapper(SimpleIndexHashMapWrapper wrapper, boolean allocateOnly) {
this.indexBasedLookup = new ArrayList>(wrapper.indexBasedLookup.size());
this.wrappedMap = new HashMap>();
ValueContainer vc;
int index = 0;
if (allocateOnly) {
for (ValueContainer key : wrapper.indexBasedLookup) {
vc = new ValueContainer(index++, key.getKey(), null);
indexBasedLookup.add(vc);
wrappedMap.put(key.getKey(), vc);
}
}
else {
for (ValueContainer key : wrapper.indexBasedLookup) {
vc = new ValueContainer(index++, key.getKey(), key.getValue());
indexBasedLookup.add(vc);
wrappedMap.put(key.getKey(), vc);
}
}
}
public SimpleIndexHashMapWrapper(K[] keys) {
this.wrappedMap = new HashMap>(keys.length * 2);
this.indexBasedLookup = new ArrayList>(keys.length);
initWithKeys(keys);
}
public SimpleIndexHashMapWrapper(K[] keys, int initialCapacity, float load) {
this.wrappedMap = new HashMap>(initialCapacity * 2, load);
this.indexBasedLookup = new ArrayList>(initialCapacity);
initWithKeys(keys);
}
public void initWithKeys(K[] keys) {
int index = 0;
ValueContainer vc;
for (K key : keys) {
vc = new ValueContainer(index++, key, null);
wrappedMap.put(key, vc);
indexBasedLookup.add(vc);
}
}
public void addKey(K key) {
ValueContainer vc = new ValueContainer(indexCounter++, key, null);
this.indexBasedLookup.add(vc);
this.wrappedMap.put(key, vc);
}
public void addKey(K key, V value) {
ValueContainer vc = new ValueContainer(indexCounter++, key, value);
this.indexBasedLookup.add(vc);
this.wrappedMap.put(key, vc);
}
public int size() {
return wrappedMap.size();
}
public boolean isEmpty() {
return wrappedMap.isEmpty();
}
public boolean containsKey(Object key) {
return wrappedMap.containsKey(key);
}
public boolean containsValue(Object value) {
return wrappedMap.containsValue(value);
}
public V get(Object key) {
return wrappedMap.get(key).getValue();
}
public V getByIndex(int index) {
return indexBasedLookup.get(index).getValue();
}
public K getKeyAtIndex(int index) {
return indexBasedLookup.get(index).getKey();
}
public int indexOf(K key) {
return wrappedMap.get(key).getIndex();
}
public V put(K key, V value) {
ValueContainer vc = wrappedMap.get(key);
if (vc == null)
throw new RuntimeException("cannot add a new entry. you must allocate a new key with addKey() first.");
indexBasedLookup.add(vc);
return wrappedMap.put(key, vc).getValue();
}
public void putAtIndex(int index, V value) {
ValueContainer vc = indexBasedLookup.get(index);
vc.setValue(value);
}
public V remove(Object key) {
throw new UnsupportedOperationException("cannot remove keys");
}
public void putAll(Map extends K, ? extends V> m) {
// wrappedMap.put
}
public void clear() {
throw new UnsupportedOperationException("cannot clear map");
}
public Set keySet() {
return wrappedMap.keySet();
}
public Collection values() {
throw new UnsupportedOperationException();
}
public Set> entrySet() {
throw new UnsupportedOperationException();
}
private class ValueContainer {
private int index;
private K key;
private V value;
public ValueContainer(int index, K key, V value) {
this.index = index;
this.key = key;
this.value = value;
}
public int getIndex() {
return index;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
void setKey(K key) {
this.key = key;
}
void setValue(V value) {
this.value = value;
}
}
}