2011-06-27 11 views
7

Dado que el STM tiene un historial de, por ejemplo, 10 valores de refs, agentes, etc., ¿se pueden leer esos valores?¿Se puede acceder a la historia de valores de STM de Can Clojure?

La razón es que estoy actualizando un montón de agentes y necesito mantener un historial de valores. Si el STM ya los conserva, preferiría usarlos. No puedo encontrar funciones en la API que parecen que leen valores del historial de STM, así que supongo que no, ni puedo encontrar ningún método en el código fuente de Java, pero tal vez no me veía bien.

+0

Sus datos son incorrectos. No hay historial que pueda leer porque no hay historial. Cuando una transacción se compromete, los valores anteriores ya no se referencian y son elegibles para la recolección de basura. – Gabe

+0

Oh, ahora veo, el historial solo se guarda durante una transacción. Gracias por la respuesta. – Hendekagon

Respuesta

9

No puede acceder directamente al historial stm de valores. Pero se puede hacer uso de add-watch para registrar la historia de los valores:

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

Cada vez que se actualiza a (la transacción se compromete STM) el valor anterior será conjed en la secuencia que se llevó a cabo en a-history.

Si desea obtener acceso a todo los valores intermedios, incluso para las transacciones deshacen puede enviar los valores a un agente durante la transacción:

(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 

Después de terminada la operación, todos los cambios a el agente r-history se ejecutará.

+1

+1. También vale la pena señalar que, en muchos casos (gracias a las estructuras de datos persistentes), mantener los valores pasados ​​utilizará significativamente menos espacio que la celebración de copias completas. Entonces, esta puede ser una forma muy eficiente de almacenar la historia. – mikera

+0

Gracias por las ideas adicionales. Al final usé un clojure.lang.PersistentQueue – Hendekagon

Cuestiones relacionadas