diff options
-rw-r--r-- | src/jvm/clojure/lang/Keyword.java | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/src/jvm/clojure/lang/Keyword.java b/src/jvm/clojure/lang/Keyword.java index ac080923..75adcdd7 100644 --- a/src/jvm/clojure/lang/Keyword.java +++ b/src/jvm/clojure/lang/Keyword.java @@ -15,18 +15,28 @@ package clojure.lang; import java.io.ObjectStreamException; import java.io.Serializable; import java.util.concurrent.ConcurrentHashMap; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; public final class Keyword implements IFn, Comparable, Named, Serializable { -private static ConcurrentHashMap<Symbol, Keyword> table = new ConcurrentHashMap(); +private static ConcurrentHashMap<Symbol, SoftReference<Keyword>> table = new ConcurrentHashMap(); +static final ReferenceQueue rq = new ReferenceQueue(); public final Symbol sym; final int hash; public static Keyword intern(Symbol sym){ + Util.clearCache(rq, table); Keyword k = new Keyword(sym); - Keyword existingk = table.putIfAbsent(sym, k); - return existingk == null ? k : existingk; + SoftReference<Keyword> existingRef = table.putIfAbsent(sym, new SoftReference<Keyword>(k,rq)); + if(existingRef == null) + return k; + Keyword existingk = existingRef.get(); + if(existingk != null) + return existingk; + //entry died in the interim, do over + return intern(sym); } public static Keyword intern(String ns, String name){ |