Hi all, this is my first post. I'm currently building a tree data structure (quadtree to be exact) while doing some exploratory game server programming using Clojure. This tree will end up with a lot of "entities" stored in the nodes, whose positions determine which node they end up in. As game state progresses, updates will come from player and AI controlled entities which need to be reflected in the tree.
Since player updates will come from any number of external clients, the tree will need some form of concurrency management. So far, I have settled on just using a single ref wrapping the root node of the tree with all update functions acting on that ref via dosync. My question is one of implementation, as I don't yet have a good feeling how different approaches to storing data will affect memory usage and performance in the long run and I'm trying to better my intuition for designing applications with Clojure. I am currently using maps to represent the nodes of the tree, with the hypothesis being that new versions of the tree will save memory and do less thrashing this way. I'm aware that Clojure's persistent data structures have some method of structural sharing between different states of the same identity, which is what leads me to that guess. I haven't found anything that conclusively says that structures defined with defrecord do not perform this sort of sharing, but from what I can tell it seems like they do not, which makes sense given that they provide accessors and expose a Java class. So, some trade-off questions would be: 1.) Does structural sharing play well with nested structures? With a tree whose nodes are represented by nested maps, if a leaf node is updated with new data, will structural sharing efficiently represent the new version of the tree as "all the rest of the tree" + modified node? 2.) If one were to use nested records instead, I assume producing a new version of the tree will result in a cloning operation over the nodes of the tree, less the nodes we are modifying ourselves. If updates were being performed very frequently, is there a possibility of adverse interaction with a GC? I know that GC implementations differ, but it seems like this could put a lot of pressure on a typical GC. 3.) Are there alternatives to a single ref around the root node of the tree that are worth exploring? I've considered wrapping each node in a ref and performing updates that way, or possibly taking the async route and dispatching cals using agents, but my experience there is nil. Any insight there? As an aside, I am not looking for specific answers as without numbers or hard data there really can't be any right now. I will end up measuring the performance of these approaches, but I do want to have some understanding of how the variables are related when trying to understand the empirical data. Thanks, Trent -- 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