summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-08-07 14:28:15 +0000
committerRich Hickey <richhickey@gmail.com>2007-08-07 14:28:15 +0000
commit7ae2f7310f3817a98c738e84e70ec69d2f60b56f (patch)
treedde267e0aadbb20703b2023bff4620cd38a86ff1
parent04c59e81c4f16bfcaef2fdfd3f5bc5d887445045 (diff)
added intern
-rw-r--r--src/jvm/clojure/lang/DynamicVar.java40
-rw-r--r--src/jvm/clojure/lang/Ref.java33
2 files changed, 72 insertions, 1 deletions
diff --git a/src/jvm/clojure/lang/DynamicVar.java b/src/jvm/clojure/lang/DynamicVar.java
index 10b3f7cd..2623fc18 100644
--- a/src/jvm/clojure/lang/DynamicVar.java
+++ b/src/jvm/clojure/lang/DynamicVar.java
@@ -12,9 +12,46 @@
package clojure.lang;
+import java.util.concurrent.ConcurrentHashMap;
+
public class DynamicVar{
final InheritableThreadLocal<Binding> dvals;
Object root;
+static ConcurrentHashMap<Symbol, DynamicVar> table = new ConcurrentHashMap<Symbol, DynamicVar>();
+
+
+public static DynamicVar intern(Symbol sym, Object root, boolean replaceRoot){
+ DynamicVar dvout = table.get(sym);
+ boolean present = dvout != null;
+
+ if(!present)
+ {
+ DynamicVar dvin = new DynamicVar(root);
+ dvout = table.putIfAbsent(sym, dvin);
+ present = dvout != dvin; //might have snuck in
+ }
+ if(present)
+ {
+ synchronized(dvout)
+ {
+ if(dvout.root == dvout.dvals || replaceRoot)
+ dvout.setRoot(root);
+ }
+ }
+ return dvout;
+}
+
+public static DynamicVar intern(Symbol sym){
+ DynamicVar dvout = table.get(sym);
+ if(dvout != null)
+ return dvout;
+
+ return table.putIfAbsent(sym, new DynamicVar());
+}
+
+public static DynamicVar find(Symbol sym){
+ return table.get(sym);
+}
public DynamicVar(){
this.dvals = new InheritableThreadLocal<Binding>();
@@ -50,8 +87,9 @@ public Object getRoot(){
return root;
}
-public void setRoot(Object root){
+synchronized public DynamicVar setRoot(Object root){
this.root = root;
+ return this;
}
public void pushThreadBinding(Object val){
diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java
index c5c667bb..86c8b9f3 100644
--- a/src/jvm/clojure/lang/Ref.java
+++ b/src/jvm/clojure/lang/Ref.java
@@ -14,6 +14,7 @@ package clojure.lang;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.UUID;
public class Ref implements IFn, Comparable<Ref>{
@@ -49,6 +50,7 @@ public static class TVal{
}
+static ConcurrentHashMap<Symbol, Ref> table = new ConcurrentHashMap<Symbol, Ref>();
TVal tvals;
final AtomicInteger faults;
@@ -87,6 +89,37 @@ public UUID getUUID(){
return uuid;
}
+public static Ref intern(Symbol sym, Object val, boolean replaceVal){
+ Ref out = table.get(sym);
+ boolean present = out != null;
+
+ if(!present)
+ {
+ Ref in = new Ref(val);
+ out = table.putIfAbsent(sym, in);
+ present = out != in; //might have snuck in
+ }
+
+ if(present && replaceVal)
+ out.set(val);
+
+ return out;
+}
+
+public static Ref intern(Symbol sym, Ref ref){
+ return table.putIfAbsent(sym, ref);
+}
+
+public static Ref intern(Symbol sym){
+ Ref ref = table.get(sym);
+ if(ref != null)
+ return ref;
+ return table.putIfAbsent(sym, new Ref());
+}
+
+public static Ref find(Symbol sym){
+ return table.get(sym);
+}
//not necessarily the latest val
// ok out of transaction