summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-08-30 14:34:29 +0000
committerRich Hickey <richhickey@gmail.com>2007-08-30 14:34:29 +0000
commitf93cacece6c5bb48d20fdbbf7b228fcdb1477981 (patch)
treed5c88d090264d8067f5b51fbcce0c72ccb7dd80d /src
parent5d1806f75ee05769a7683afc806c389091667e04 (diff)
keyword interning, identity equality
Diffstat (limited to 'src')
-rw-r--r--src/jvm/clojure/lang/Keyword.java39
-rw-r--r--src/jvm/clojure/lang/LispReader.java2
-rw-r--r--src/jvm/clojure/lang/RT.java2
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"));