diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-08-07 14:28:15 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-08-07 14:28:15 +0000 |
commit | 7ae2f7310f3817a98c738e84e70ec69d2f60b56f (patch) | |
tree | dde267e0aadbb20703b2023bff4620cd38a86ff1 | |
parent | 04c59e81c4f16bfcaef2fdfd3f5bc5d887445045 (diff) |
added intern
-rw-r--r-- | src/jvm/clojure/lang/DynamicVar.java | 40 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Ref.java | 33 |
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 |