Re: custom tree model, iters, and memory management



Kristian Rietveld wrote:
Hi,

On Sun, Jul 26, 2009 at 8:22 PM, Thomas Stover<thomas wsinnovations com> wrote:
While working on a custom tree model (thanks to Tim-Philipp Müller for the
tutorial), I needed more pointers in my iter structure than the user_data,
user_data2, and user_data3. So I defined a new structure and stored that in
user_data. For the model's _get_iter(), _iter_children(), _iter_parent(),
iter_nth_child() methods, if the "output" iter's user_data is NULL, a new
one of these "extra pointers structures" gets allocated. At the moment, all
of these allocations get also referenced in a GSList in the custom model,
and freed when the model is finalized. While this does work ok, it feels
strange. Any thoughts? Some light analysis shows the treeview doesn't use
that many iters, so maybe this is fine?

Feels strange indeed :)  One of the problems is that you do not really
know when an iterator is no longer used.  This also depends on whether
your model hands out persistent or non-persistent iterators.
Persistent iterators stay valid for ever, non-persistent stay valid
until the model changes its stamp, which is whenever the internal data
structure of the model changes in such a way that the iterator for the
same node will be different.  For the persistent case, you need to
keep all these extra allocated structures around until finalization,
if you really allocate a new structure for every iterator handed out,
the memory usage here is not bounded.

I would suggest you to have a look at how GtkTreeModelSort and
GtkTreeModelFilter handle this.  A valid iterator only exists for a
row in your model.  You can group all the data you need for each row
in a structure and group these structures in a list or tree form
representing the layout of your model.  Each row now has a structure
with all required data and is accessible by a pointer.  Instead of
allocating a new structure for each iterator, put the pointer to the
(already allocated) structure in the model's internal data structure
in the iterator's user_data pointer.  No need to allocate a new
structure each time and the other model methods of your model can use
the pointer in the iterator's user_data to access the internal data
structure.

Hope this helps and clear things up a bit.


regards,

-kris.
Thanks for the input. Ideally iters would have an optional callback to free private data, but I think understand the thinking behind the design more now. It seems the custom model approach would be best if, as you describe, you can just point iters to real data nodes directly. In may case I think it is going to be worth going back to the source data store that I'm providing an optional gtk tree model wrapper for, and redoing it slightly so that every leaf depth uses the same base C structure, enabling me to do that.

People like to say that low level Gtk+ is a rough edge, and while it is in deed something one has to "learn to love", there is just no substitute for the power and flexibility it offers. This being an excellent example. Thanks again Gtk world.

On the same topic, I'm trying to think of the best way to deal with the performance of deriving iterators from paths in a case like mine. Essentially I have linked lists that right now have to be traversed through to the the Nth position to resolve a path of N for a given depth. I could store another table somewhere with indexes mapped to pointers, but this table itself would have to be dynamically resized and completely rebuilt every time the data changed, virtually defeating the point of the linked list.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]