diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-01-20 23:48:34 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-01-20 23:48:34 +0000 |
commit | 06d3b59c23ef90c9410470652ed6fc408d360716 (patch) | |
tree | ebf9e5cf6ba2b73018cbb945e846872a8b60959a | |
parent | 9c1ca8132937642298ad3c4b4cee6fa464a36633 (diff) |
added overloads for Atom.swap
fix RT.nth for Lists to use count only for RandomAccess
-rw-r--r-- | src/clj/clojure/core.clj | 5 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Atom.java | 49 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 2 |
3 files changed, 52 insertions, 4 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index d21c3f02..1b0d1484 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1197,7 +1197,10 @@ (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in." - [#^clojure.lang.Atom atom f & args] (.swap atom f args)) + ([#^clojure.lang.Atom atom f] (.swap atom f)) + ([#^clojure.lang.Atom atom f x] (.swap atom f x)) + ([#^clojure.lang.Atom atom f x y] (.swap atom f x y)) + ([#^clojure.lang.Atom atom f x y & args] (.swap atom f x y args))) (defn compare-and-set! "Atomically sets the value of atom to newval if and only if the diff --git a/src/jvm/clojure/lang/Atom.java b/src/jvm/clojure/lang/Atom.java index eb904c8f..3d02f6e4 100644 --- a/src/jvm/clojure/lang/Atom.java +++ b/src/jvm/clojure/lang/Atom.java @@ -30,11 +30,56 @@ public class Atom extends ARef{ return state.get(); } - public Object swap(IFn f, ISeq args) throws Exception { + public Object swap(IFn f) throws Exception { for(;;) { Object v = get(); - Object newv = f.applyTo(new Cons(v, args)); + Object newv = f.invoke(v); + validate(newv); + if(state.compareAndSet(v,newv)) + { + if(v != newv) + notifyWatches(); + return newv; + } + } + } + + public Object swap(IFn f, Object arg) throws Exception { + for(;;) + { + Object v = get(); + Object newv = f.invoke(v,arg); + validate(newv); + if(state.compareAndSet(v,newv)) + { + if(v != newv) + notifyWatches(); + return newv; + } + } + } + + public Object swap(IFn f, Object arg1, Object arg2) throws Exception { + for(;;) + { + Object v = get(); + Object newv = f.invoke(v, arg1, arg2); + validate(newv); + if(state.compareAndSet(v,newv)) + { + if(v != newv) + notifyWatches(); + return newv; + } + } + } + + public Object swap(IFn f, Object x, Object y, ISeq args) throws Exception { + for(;;) + { + Object v = get(); + Object newv = f.applyTo(RT.listStar(v, x, y, args)); validate(newv); if(state.compareAndSet(v,newv)) { diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index f5d97e83..a277f89e 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -760,7 +760,7 @@ static public Object nth(Object coll, int n, Object notFound){ return Reflector.prepRet(Array.get(coll, n)); return notFound; } - else if(coll instanceof List) + else if(coll instanceof RandomAccess) { List list = (List) coll; if(n < list.size()) |