001: package sisc.modules.hashtable;
002:
003: import sisc.data.*;
004: import java.util.Map;
005: import java.lang.ref.ReferenceQueue;
006: import java.lang.ref.WeakReference;
007:
008: public class WeakHashtable extends Hashtable {
009:
010: private ReferenceQueue garbage = new ReferenceQueue();
011:
012: public WeakHashtable() {
013: super ();
014: }
015:
016: public WeakHashtable(Procedure equalsProc, Procedure hashProc) {
017: super (equalsProc, hashProc);
018: }
019:
020: private class Key extends WeakReference implements HashtableKey {
021:
022: private int hash;
023:
024: public Key(Value key) {
025: super (key, garbage);
026: //we need to memoize the hash code so that it remains
027: //available even after the key has become garbage
028: hash = callHashCode(key);
029: }
030:
031: public Value getValue() {
032: return (Value) get();
033: }
034:
035: public boolean equals(Object o) {
036: //This first test is important: we need it in order to be
037: //able to remove keys that have become garbage.
038: if (o == this )
039: return true;
040:
041: if (!(o instanceof Key))
042: return false;
043:
044: Value myVal = getValue();
045: Value otherVal = ((Key) o).getValue();
046: //A garbage key can never be equal to another garbage key
047: return (myVal != null) && (otherVal != null)
048: && callEquals(myVal, otherVal);
049: }
050:
051: public int hashCode() {
052: return hash;
053: }
054:
055: }
056:
057: protected HashtableKey makeKey(Value k) {
058: return new Key(k);
059: }
060:
061: protected Map getMap() {
062: Map ht = super .getMap();
063: Object r;
064: while ((r = garbage.poll()) != null) {
065: ht.remove(r);
066: }
067:
068: return ht;
069: }
070:
071: public boolean valueEqual(Value v) {
072: if (!(v instanceof WeakHashtable))
073: return false;
074: return super .valueEqual(v);
075: }
076: }
077:
078: /*
079: * The contents of this file are subject to the Mozilla Public
080: * License Version 1.1 (the "License"); you may not use this file
081: * except in compliance with the License. You may obtain a copy of
082: * the License at http://www.mozilla.org/MPL/
083: *
084: * Software distributed under the License is distributed on an "AS
085: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
086: * implied. See the License for the specific language governing
087: * rights and limitations under the License.
088: *
089: * The Original Code is the Second Interpreter of Scheme Code (SISC).
090: *
091: * The Initial Developer of the Original Code is Scott G. Miller.
092: * Portions created by Scott G. Miller are Copyright (C) 2000-2007
093: * Scott G. Miller. All Rights Reserved.
094: *
095: * Contributor(s):
096: * Matthias Radestock
097: *
098: * Alternatively, the contents of this file may be used under the
099: * terms of the GNU General Public License Version 2 or later (the
100: * "GPL"), in which case the provisions of the GPL are applicable
101: * instead of those above. If you wish to allow use of your
102: * version of this file only under the terms of the GPL and not to
103: * allow others to use your version of this file under the MPL,
104: * indicate your decision by deleting the provisions above and
105: * replace them with the notice and other provisions required by
106: * the GPL. If you do not delete the provisions above, a recipient
107: * may use your version of this file under either the MPL or the
108: * GPL.
109: */
|