001: /**
002: *
003: */package org.drools.util;
004:
005: import org.drools.util.AbstractHashTable.EqualityEquals;
006:
007: public class ObjectHashMap extends AbstractHashTable {
008:
009: private static final long serialVersionUID = 400L;
010:
011: public ObjectHashMap() {
012: this (16, 0.75f);
013: }
014:
015: public ObjectHashMap(final int capacity, final float loadFactor) {
016: super (capacity, loadFactor);
017: }
018:
019: public ObjectHashMap(final Entry[] table) {
020: super (0.75f, table);
021: }
022:
023: public ObjectHashMap(final float loadFactor, final Entry[] table) {
024: super (loadFactor, table);
025: }
026:
027: public Object put(final Object key, final Object value) {
028: return put(key, value, true);
029: }
030:
031: public void clear() {
032: this .table = new Entry[Math.min(this .table.length, 16)];
033: this .threshold = (int) (this .table.length * this .loadFactor);
034: }
035:
036: public Object put(final Object key, final Object value,
037: final boolean checkExists) {
038: final int hashCode = this .comparator.hashCodeOf(key);
039: final int index = indexOf(hashCode, this .table.length);
040:
041: // scan the linked entries to see if it exists
042: if (checkExists) {
043: ObjectEntry current = (ObjectEntry) this .table[index];
044: while (current != null) {
045: if (hashCode == current.hashCode
046: && this .comparator.equal(key, current.key)) {
047: final Object oldValue = current.value;
048: current.value = value;
049: return oldValue;
050: }
051: current = (ObjectEntry) current.getNext();
052: }
053: }
054:
055: // We aren't checking the key exists, or it didn't find the key
056: final ObjectEntry entry = new ObjectEntry(key, value, hashCode);
057: entry.next = this .table[index];
058: this .table[index] = entry;
059:
060: if (this .size++ >= this .threshold) {
061: resize(2 * this .table.length);
062: }
063: return null;
064: }
065:
066: public Object get(final Object key) {
067: final int hashCode = this .comparator.hashCodeOf(key);
068: final int index = indexOf(hashCode, this .table.length);
069:
070: ObjectEntry current = (ObjectEntry) this .table[index];
071: while (current != null) {
072: if (hashCode == current.hashCode
073: && this .comparator.equal(key, current.key)) {
074: return current.value;
075: }
076: current = (ObjectEntry) current.getNext();
077: }
078: return null;
079: }
080:
081: public Object remove(final Object key) {
082: final int hashCode = this .comparator.hashCodeOf(key);
083: final int index = indexOf(hashCode, this .table.length);
084:
085: ObjectEntry previous = (ObjectEntry) this .table[index];
086: ObjectEntry current = previous;
087: while (current != null) {
088: final ObjectEntry next = (ObjectEntry) current.getNext();
089: if (hashCode == current.hashCode
090: && this .comparator.equal(key, current.key)) {
091: if (previous == current) {
092: this .table[index] = next;
093: } else {
094: previous.setNext(next);
095: }
096: current.setNext(null);
097: this .size--;
098: return current.value;
099: }
100: previous = current;
101: current = next;
102: }
103: return null;
104: }
105:
106: public Entry getBucket(final Object object) {
107: final int hashCode = this .comparator.hashCodeOf(object);
108: final int index = indexOf(hashCode, this .table.length);
109:
110: return this .table[index];
111: }
112:
113: public static class ObjectEntry implements Entry {
114:
115: private static final long serialVersionUID = 400L;
116:
117: private Object key;
118:
119: private Object value;
120:
121: private int hashCode;
122:
123: private Entry next;
124:
125: public ObjectEntry(final Object key, final Object value,
126: final int hashCode) {
127: this .key = key;
128: this .value = value;
129: this .hashCode = hashCode;
130: }
131:
132: public Object getValue() {
133: return this .value;
134: }
135:
136: public Object getKey() {
137: return this .key;
138: }
139:
140: public Entry getNext() {
141: return this .next;
142: }
143:
144: public void setNext(final Entry next) {
145: this .next = next;
146: }
147:
148: public int hashCode() {
149: return this .hashCode;
150: }
151:
152: public boolean equals(final Object object) {
153: if (object == this ) {
154: return true;
155: }
156:
157: // assumes we never have null or wrong class
158:
159: final ObjectEntry other = (ObjectEntry) object;
160: return this.key.equals(other.key)
161: && this.value.equals(other.value);
162: }
163: }
164: }
|