All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mvel2.util.SimpleIndexHashMapWrapper Maven / Gradle / Ivy

There is a newer version: 4.15.102
Show newest version
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 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;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy