diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-07-16 08:40:53 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-07-16 08:48:14 -0400 |
commit | ed89fd14b2d9d6fbe71e439db2ce20237c5d434f (patch) | |
tree | 1360fd663946493c948b883fec354a19c16dc513 | |
parent | 758672ecd0e8f10bb9598769da307776d6d15a71 (diff) |
use soft refs for keyword intern table
-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){ |