On Jul 13, 1:39 pm, "sailormoo...@gmail.com" <sailormoo...@gmail.com> wrote: > Hi : > > I would like to simulate a simple database with the STM of clojure. > The rules are > 1. There can be many rooms, and each room has its own attirbute > 2. One room contains many people, and each person has its own > attribute > 3. rooms can be created, and deleted, and people can be added into or > removed from room. > > So I made a globle variable *rooms*, > where *rooms* is a reference of a sequence of references of rooms, > where room is a hashmap, with an attribute of reference of a sequence > of references of people. > > Just like this, > (def *rooms* (ref {"room_1" (ref {:players (ref [(ref > player)])} ) } ) ) > > Ouch, it has 4 refs @@ > I think it's hard to control, but why did I make that many ref? > If there is fewer refs, the functions that alter might need to see > outer ref to do an alter. > > Any one got an idea to make the code easier ?? Thanks
You don't need refs for everything you might want to change; having fewer refs just means you have coarser granularity for updates, thus *possibly* reducing concurrency or scalability. However, the fewer refs you have, the easier they are to manipulate. It's a matter of finding balance. I would start with a single ref *rooms* which could be a map of room- name -> ref to room, which in turn would contain a set of unique player IDs. Note: Having the room wrapped in a ref is enough. Replacing the entire room map when you need to add to the set of joined players is likely about as expensive as having to deal with two refs. It might even be faster. Then, keep a separate ref to a *players* map which maps a given id number to the player's information map, which does not have to be a ref, again because updating the entire player map is not that expensive. There are other approaches, but I think when starting to code, it's good to keep the number of refs to a minimum. Also, when coding the ref-altering functions, resist having the dosync blocks inside the smallest functions; that is, instead of a join-room fn that contains a dosync, have a join-room that takes a room data structure and a player id/whatever, then returns a new room data structure, and use that function with alter. Or, put another way, consider functions containing 'dosync impure, and as such, try to keep them in one place instead of scattering them around. :) -- Jarkko --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---