Thank you! Great question. I couldn't devise a way to merge concurrent changes in a HashMap using Clojure's STM. A while ago I discussed it with Christophe Grand and he had his own idea about how to fix it: [1] and [2]. IIRC Christophe's solution may see a conflict even if there's no real conflict due to stochastic nature of the implementation.
I had this use case in my project that functions as a reservation system, I needed a way to add a record into the Map saying that a given device has been reserved by a given user. Since I didn't know all the devices in advance I needed a way to detect conflicts even if Key/Value pair is added for the first time or when it is removed completely. [1] http://clj-me.cgrand.net/2011/10/06/a-world-in-a-ref/ [2] http://clj-me.cgrand.net/2012/09/21/follow-up-a-world-in-a-ref/ On Sunday, August 18, 2013 12:42:23 PM UTC+2, Hussein B. wrote: > > Great ! Congratulations! > > How it does compare with Clojure's builtin STM? > > Thanks. > > On Sunday, August 18, 2013 10:24:48 AM UTC+2, Ivan Koblik wrote: >> >> Hi All, >> >> Almost 4 years ago I developed STM with semantic concurrency control for >> my project at CERN. Main feature of this STM is the TransactionalMap that >> lets you merge concurrent changes. Library is heavily tested and is very >> stable. It has been used in production for the past 2 years. >> >> Recently I released it on GitHub: >> http://entwined.koblik.ch (will redirect to >> https://github.com/CERN-BE/Entwined-STM) >> >> Since Entwined STM was designed to be used from Java I wrote a simple >> facade for it in Clojure that you can load with >> >> (require '[cern.entwined.core :as stm]) >> >> Entwined STM operates on a memory with a fixed structure, meaning that >> you have to define what and how many collections you want to have in your >> STM and this can't be changed after construction. To construct memory with >> 1 transactional map and 1 transactional queue run this: >> >> (def memory (stm/create-memory :map (stm/create-map) :queue >> (stm/create-queue))) >> >> It's impossible to access transactional entities outside of a >> transaction, to run a transaction you can use "intrans" macro >> >> (stm/intrans memory data (-> data :map (.put :key1 "value1")) true) >> >> (stm/intrans memory data (-> data :map (.get :key1))) ;-> "value1" >> >> First line puts [:key1 "value1"] pair into the map. True at the end of >> the body tells the memory to commit this transaction. intrans will initiate >> commit if body returns truthy value. Second line just shows that the change >> has been committed. >> >> A couple more words on the implementation: I used HashMap to implement >> the TransactionalMap, I copy the backing map for every transaction which >> may be expensive for some scenarios. Obvious solution would be to use >> Clojure's persistent map. Commits are eventually serialized and protected >> with a single lock. If you take a look at the Java source you'll see that >> Transaction interface has a second method "committed" that is called when >> commit is being done. I use this method to write to the hardware knowing >> that execution order of committed callbacks is the same as the commit order. >> >> I would greatly appreciate any feedback and suggestions. If you have any >> questions don't hesitate to ask here or email me directly. Documentation is >> still somewhat lacking and I'd be interested to know which parts of it >> should be improved first. >> >> Cheers, >> Ivan. >> > -- -- 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/groups/opt_out.