001: package org.mvel.util;
002:
003: import java.util.AbstractMap;
004: import java.util.Set;
005: import java.util.Map;
006:
007: public class FastMap<K, V> extends AbstractMap<K, V> {
008: private Set entrySet;
009: private Node[] values;
010: private int size;
011: private boolean init = false;
012:
013: private Object[] lateInitKeys;
014: private Object[] lateInitVals;
015:
016: public FastMap(int size, Object[] keys, Object[] values) {
017: this .size = size;
018: lateInitKeys = keys;
019: lateInitVals = values;
020: }
021:
022: public FastMap(int capacity) {
023: entrySet = new FastSet(capacity);
024: values = new Node[capacity * 2];
025:
026: lateInitKeys = new Object[capacity];
027: lateInitVals = new Object[capacity];
028: }
029:
030: public Set entrySet() {
031: return entrySet;
032: }
033:
034: public V put(Object key, Object value) {
035: if (!init) {
036: lateInitKeys[size] = key;
037: lateInitVals[size] = value;
038:
039: size++;
040: return null;
041: }
042:
043: size++;
044:
045: entrySet.add(key);
046:
047: int target = hash(key);
048:
049: if (values[target] != null)
050: values[target] = values[target].add(key, value);
051: else
052: values[target] = new Node(key, value);
053:
054: return null;
055: }
056:
057: public boolean containsKey(Object key) {
058: return get(key) != null;
059: }
060:
061: public V get(Object key) {
062: if (!init) {
063: initialize();
064: }
065:
066: return (V) values[hash(key)].getValue(key);
067: }
068:
069: private void initialize() {
070: int preInitSize = size;
071: size = 0;
072: init = true;
073: entrySet = new FastSet(preInitSize);
074: values = new Node[preInitSize * 2];
075: for (int i = 0; i < preInitSize; i++) {
076: put(lateInitKeys[i], lateInitVals[i]);
077: }
078: }
079:
080: public int size() {
081: return size;
082: }
083:
084: public boolean isEmpty() {
085: return size == 0;
086: }
087:
088: public int hash(Object key) {
089: int hashCode = key.hashCode();
090: hashCode ^= (hashCode >>> 20) ^ (hashCode >>> 12);
091: return (hashCode ^ (hashCode >>> 7) ^ (hashCode >>> 4))
092: & values.length - 1;
093: }
094:
095: public static class Node<K, V> {
096: private Node next;
097: private K key;
098: private V value;
099:
100: public Node(K key, V value) {
101: this .key = key;
102: this .value = value;
103: }
104:
105: public V getValue(K key) {
106: Node n = this ;
107: do {
108: if (key.equals(n.key))
109: return value;
110: } while ((n = next) != null);
111:
112: return null;
113: }
114:
115: public Node add(K key, V value) {
116: Node n = new Node(key, value);
117: n.next = this ;
118: return n;
119: }
120:
121: public String toString() {
122: return String.valueOf(value);
123: }
124: }
125:
126: public boolean equals(Object o) {
127: if (!(o instanceof Map))
128: return false;
129: if (!init)
130: initialize();
131:
132: if ((o instanceof FastMap) && !((FastMap) o).init)
133: ((FastMap) o).initialize();
134:
135: if (o instanceof FastMap)
136: return entrySet.equals(((FastMap) o).entrySet);
137: else {
138: Map map = (Map) o;
139: Object v;
140: for (Object key : map.keySet()) {
141: v = map.get(key);
142: if (v == null) {
143: if (get(key) == null)
144: continue;
145: else
146: return false;
147: }
148: if (!v.equals(get(key)))
149: return false;
150: }
151: return true;
152: }
153: }
154:
155: public int hashCode() {
156: if (!init)
157: initialize();
158: int h = 0;
159: for (Object o : entrySet) {
160: h += o.hashCode();
161: }
162:
163: return h;
164: }
165:
166: public String toString() {
167: return String.valueOf(values);
168: }
169: }
|