2011-06-27 8 views
7

STMに、たとえばREFERの10個の値の履歴があるとすれば、エージェントなどはその値を読み取ることができますか?ClojureのSTMの値の履歴にアクセスできますか?

理由は、私はエージェントの負荷を更新しており、値の履歴を保持する必要があるからです。 STMがすでにそれらを保管している場合、私はむしろそれらを使用したいと思います。私はSTMの履歴から値を読み取るように見えるAPI内の関数を見つけることができないので、私は推測しませんし、javaソースコード内のメソッドを見つけることもできません。

+0

あなたの存在は間違っています。歴史がないのであなたが読むことができる歴史はありません。トランザクションがコミットすると、古い値は参照されなくなり、ガベージコレクションの対象となります。 – Gabe

+0

ああ、私は今見ます、履歴はトランザクション中に開催されます。答えをありがとう。 – Hendekagon

答えて

9

値のstm履歴に直接アクセスすることはできません。しかし、あなたはadd-watchの使用は値の履歴を記録することができます:

(def a-history (ref [])) 
(def a (agent 0)) 
(add-watch a :my-history 
    (fn [key ref old new] (alter a-history conj old))) 

aが更新されるたびに(STMトランザクションはコミット)古い値がa-historyで開催されたシーケンスにconjedされます。

あなたがトランザクション中にエージェントに値を送ることができるとしてもロールバックされたトランザクションのためのすべての中間値へのアクセスを、取得したい場合は、次のトランザクションが終了した後に、

(def r-history (agent []) 
(def r (ref 0)) 
(dosync (alter r 
      (fn [new-val] 
      (send r-history conj new-val) ;; record potential new value 
      (inc r))))     ;; update ref as you like 

すべての変更をエージェントr-historyが実行されます。

+1

+1。多くの場合(永続的なデータ構造のおかげで)、過去の値はコピー全体を保持するよりもはるかに少ない領域を使用することに留意する価値があります。これは、実際にはスペースを効率的に使用して履歴を保存する方法です。 – mikera

+0

追加のアイデアありがとう。最後に私はclojure.lang.PersistentQueueを使いました – Hendekagon

関連する問題