Re: STM history queues, when is a snapshot pushed

2014-03-24 Thread Greg D
Having learned a little more about refs and transactions from M. Fogus and 
C. Houser The Joy of Clojure, Second Editionhttp://www.manning.com/fogus2/, 
I altered the stress-ref function from 10.2.4. Using Clojure 1.5.1:

(defn stress-ref [r]
  (let [slow-tries (atom 0)]
(future
 (dosync
  (swap! slow-tries inc)
  (Thread/sleep 200)
  @r)
 (println (format r is: %s, meta: %s, history: %d, after: %d tries
  @r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
  (Thread/sleep 10)
  (dosync (alter r #(let [r0 (first %)]
 (condp = r0
 :identical %
 := (with-meta % {:mkw (inc (:mkw (meta 
%)))})
 (with-meta [(inc r0)] {:mkw (inc (:mkw (meta 
%)))}))
:done))

Using this function in the following ways
user= (stress-ref (ref (with-meta [:identical] {:mkw 0})))
:done
r is: [:identical], meta: {:mkw 0}, history: 10, after: 26 tries

user= (stress-ref (ref (with-meta [:=] {:mkw 0})))
:done
r is: [:=], meta: {:mkw 500}, history: 10, after: 26 tries

user= (stress-ref (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries

From these results I infer that a snapshot is pushed to history whenever 
alter (et al) are used. Any efficiencies need to be implemented in the 
Clojure code, eg.
(defn stress-ref-equal [r]
  (let [slow-tries (atom 0)]
(future
 (dosync
  (swap! slow-tries inc)
  (Thread/sleep 200)
  @r)
 (println (format r is: %s, meta: %s, history: %d, after: %d tries
  @r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
  (Thread/sleep 10)
  (dosync (let [r0 (first @r)]
(condp = r0
:identical (ensure r)
:= (ensure r)
(alter r #(with-meta [(inc r0)] {:mkw (inc (:mkw (meta 
%)))}))
:done))

user= (stress-ref-equal (ref (with-meta [:identical] {:mkw 0})))
r is: [:identical], meta: {:mkw 0}, history: 0, after: 1 tries
:done

user= (stress-ref-equal (ref (with-meta [:=] {:mkw 0})))
r is: [:=], meta: {:mkw 0}, history: 0, after: 1 tries
:done

user= (stress-ref-equal (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries

The documentation at Refs and Transactions http://clojure.org/refs only 
refers to change without defining what is meant by change. Given the 
admonition not to rely on inferences as made above, what's a coder to do? 
Future optimization of refs and transactions may break the code.

As a beginner, I can't tell if I'm just confused, or if this is actually 
confusing.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


STM history queues, when is a snapshot pushed

2014-03-23 Thread Greg D
Is a new snapshot pushed onto the history queue of a ref when

   1. every time the ref is a target of alter, commute, ref-set, reset, 
   alter-meta!, or reset-meta!, or
   2. only when the committed value for the ref is not identical to the 
   value at the end of the history queue?
   
When checking the committability of a ref before the end of a transaction, 
is the check that

   1. the end position of the history queue for that ref is the same as it 
   was at the beginning of the transaction, or
   2. the value of the ref at the end of the history queue is identical to 
   the value at the beginning of the transaction?

For both questions, choice 1 appears to be unquestionable safe, but could 
sponsor a higher number of retries. The choice 2s may conserve some 
retries, but I'm not sure about the safety. 

For both questions, the implementation complexity and efficiency seem 
similar.

At any rate, the actual implementation is not a part of the documented API, 
yet could affect how one codes transaction functions. Even if I dug through 
the Java source to form my own impressions, one is not supposed to rely on 
such behaviour.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.