diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-07-30 19:26:01 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-07-30 19:26:01 +0000 |
commit | 0a6ceab0717beeabef24062d68449a8147ed9e22 (patch) | |
tree | 15857b35b9598b8b249afce55a82705ef7a47760 /src | |
parent | bd6e6a16c32f15713a351263a07c384a19c2d21d (diff) |
added cached val for non-locked, non-current reads
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/LockingTransaction.java | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Ref.java | 41 |
2 files changed, 38 insertions, 11 deletions
diff --git a/src/jvm/clojure/lang/LockingTransaction.java b/src/jvm/clojure/lang/LockingTransaction.java index 093ad2d6..8ee7678d 100644 --- a/src/jvm/clojure/lang/LockingTransaction.java +++ b/src/jvm/clojure/lang/LockingTransaction.java @@ -437,9 +437,11 @@ public static void main(String[] args){ for(Ref tref : items) { //Transaction.get().doTouch(tref); - LockingTransaction t = LockingTransaction.getEx(); - int val = (Integer) t.doGet(tref); - t.doSet(tref, val + 1); +// LockingTransaction t = LockingTransaction.getEx(); +// int val = (Integer) t.doGet(tref); +// t.doSet(tref, val + 1); + int val = (Integer) tref.get(); + tref.set(val + 1); } return null; } diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java index 6c1f9bcd..6e2e3351 100644 --- a/src/jvm/clojure/lang/Ref.java +++ b/src/jvm/clojure/lang/Ref.java @@ -55,20 +55,21 @@ public static class TVal{ final static AtomicLong ids = new AtomicLong(); -TVal tvals; - -AtomicInteger faults; +TVal tvals; +final AtomicInteger faults; transient volatile InheritableThreadLocal<Binding> dvals; final ReentrantReadWriteLock lock; LockingTransaction.Info tinfo; final long id; +transient volatile Object cached; public Ref(){ this.tvals = null; this.dvals = null; this.tinfo = null; faults = new AtomicInteger(); + this.cached = faults; //use faults as magic never-been-set value lock = new ReentrantReadWriteLock(); id = ids.getAndIncrement(); } @@ -78,7 +79,31 @@ public Ref(Object initVal){ tvals = new TVal(initVal, 0, System.currentTimeMillis()); } -//ok out of transaction +//not necessarily the latest val + +// ok out of transaction +public Object cachedVal(){ + Binding b = getThreadBinding(); + if(b != null) + return b.val; + if(cached != faults) + return cached; + try + { + lock.readLock().lock(); + if(tvals != null) + return cached = tvals.val; + throw new IllegalStateException(this.toString() + " is unbound."); + } + finally + { + lock.readLock().unlock(); + } +} + +//the latest val + +// ok out of transaction public Object currentVal(){ Binding b = getThreadBinding(); if(b != null) @@ -87,7 +112,7 @@ public Object currentVal(){ { lock.readLock().lock(); if(tvals != null) - return tvals.val; + return cached = tvals.val; throw new IllegalStateException(this.toString() + " is unbound."); } finally @@ -125,11 +150,11 @@ public void popThreadBinding() throws Exception{ //* //must be dynamically bound or transactional read -public Object val() throws Exception{ +public Object get() throws Exception{ Binding b = getThreadBinding(); if(b != null) return b.val; - return LockingTransaction.getEx().doGet(this); + return cached = LockingTransaction.getEx().doGet(this); } public Object set(Object val) throws Exception{ @@ -186,7 +211,7 @@ void trimHistory(){ final public IFn fn(){ - return (IFn) currentVal(); + return (IFn) cachedVal(); } public Object invoke() throws Exception{ |