diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-08-30 14:34:29 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-08-30 14:34:29 +0000 |
commit | f93cacece6c5bb48d20fdbbf7b228fcdb1477981 (patch) | |
tree | d5c88d090264d8067f5b51fbcce0c72ccb7dd80d /src | |
parent | 5d1806f75ee05769a7683afc806c389091667e04 (diff) |
keyword interning, identity equality
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/Keyword.java | 39 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 2 |
3 files changed, 13 insertions, 30 deletions
diff --git a/src/jvm/clojure/lang/Keyword.java b/src/jvm/clojure/lang/Keyword.java index ccdca37d..1576a20d 100644 --- a/src/jvm/clojure/lang/Keyword.java +++ b/src/jvm/clojure/lang/Keyword.java @@ -12,45 +12,28 @@ package clojure.lang; - -public class Keyword implements IFn{ +import java.util.concurrent.ConcurrentHashMap; -/** - * Used by intern() - * - * @param name - */ +public class Keyword implements IFn{ +private static ConcurrentHashMap<Symbol, Keyword> table = new ConcurrentHashMap(); public final Symbol sym; -final int hash; -public Keyword(Symbol sym){ - this.sym = sym; - this.hash = RT.hashCombine(":".hashCode(), sym.hashCode()); +public static Keyword intern(Symbol sym){ + Keyword k = new Keyword(sym); + Keyword existingk = table.putIfAbsent(sym, k); + return existingk == null ? k : existingk; } -public Keyword(String ns, String name){ - this(Symbol.intern(ns, name)); +public static Keyword intern(String ns, String name){ + return intern(Symbol.intern(ns, name)); } -public boolean equals(Object o){ - if(this == o) - return true; - if(o == null || !(o instanceof Keyword)) - return false; - - Keyword keyword = (Keyword) o; - - //identity compares intended, names are interned - return sym.equals(keyword.sym); -} - -public int hashCode(){ - return hash; +private Keyword(Symbol sym){ + this.sym = sym; } - public String toString(){ return ":" + sym; } diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 3556fbe9..01614c78 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -268,7 +268,7 @@ private static Object matchSymbol(String s){ boolean isKeyword = s.charAt(0) == ':';
Symbol sym = Symbol.intern(s.substring(isKeyword ? 1 : 0));
if(isKeyword)
- return new Keyword(sym);
+ return Keyword.intern(sym);
return sym;
}
return null;
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 94451504..0069ffd7 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -21,7 +21,7 @@ public class RT{ static public Symbol T = Symbol.create(null, "t"); final static public DynamicVar OUT = DynamicVar.intern(Symbol.create("clojure", "out"), new OutputStreamWriter(System.out)); -final static Keyword TAG_KEY = new Keyword("clojure", "tag"); +final static Keyword TAG_KEY = Keyword.intern("clojure", "tag"); final static public DynamicVar CURRENT_MODULE = DynamicVar.intern(Symbol.create("clojure", "current-module"), Module.findOrCreateModule("clojure/user")); |