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