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

Reply via email to