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:45:30 -0400 |
commit | 02559a4aad442253b601870f7c9aa04c91baf235 (patch) | |
tree | c3c5ce423f8b91e5fd909b4c3b7f646a5f87af1d | |
parent | da14cbb99fd5a3ccb4092fe629822a86065e6fb9 (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){ |