Re: [Evolution-hackers] [maybe OT?] Code excerpts from Evolution



On Tue, 2005-05-03 at 10:38 +0530, Not Zed wrote:
> This isn't quite right.  It doesn't use a gtree to track the chunks,
> it uses it to calculate the unused chunks.  Subtle difference - in
> that the tree is used as a one-off structure during the clean process,
> not as long-term tracking structure.

Many thanks!  OK, I've updated that mention:

http://infoether.com/~tom/evolution_snippets.html

> We actually don't use g* collections for many things we might, because
> of efficiency & preference issues. 

Yeah, I'd noticed that... I was kind of surprised!

> e.g. edlist is a double-linked list implementation which has O(1)
> append and prepend, and O(1) removal of head and tail nodes.  GList
> has O(N) append and O(N) removal of the tail node.  This often leads
> to unecessary and inefficient code such as g_list_reverse, or having
> to manually track the tail node which is prone to coding mistakes. 

Argh.

>  It also means you can't re-use the same simple code as a stack, a
> queue, or an ordered list without a performance penalty in some of the
> cases - there are even more special api's for each case.

GQueue is a bit of an odd one; I was surprised to see all those insert
and remove functions.  Seems a bit unqueueish....

> In general, the glib collections: 
>       * have inconsistent interfaces, e.g. g_ptr_array_add vs
>         g_*array*append, g_list_free vs g_hash_table_destroy,
>         g_list_nth vs g_array_index, g_list_length vs
>         g_hash_table_size, etc. 

Heh, yes, very true, I'm making sure to note those in the tutorial.  

>       * most of the interfaces are over-designed - glist has 30
>         functions and 2 macros. 
>       * are not very well implemented, generally each is implemented
>         separately with no overlap (glist vs gslist, g*array vs
>         gstring), or the overlap and 'subclassing' is funny (e.g.
>         g*array). 

Yeah, GPtrArray and GByteArray are declared inside GArray... rather odd.

>       * cannot be subclassed or extended in any way.  not even
>         internally!  e.g. GQueue vs GList. 
>       * often can only be iterated using callbacks, without iterators,
>         making some code much more complex and less efficient than
>         needed (e.g. requiring one-off callback data structures to be
>         written).  A particularly bad case is GHashTable. 

Hm, I found those kind of handy... especially when you could pass, say,
g_free to foreach.  But I haven't been using them very long...

>       * provide zero type safety.  At least if the base structures
>         could be extended they could provide some type safety.  e.g.
>         edlist provides data node type safety at least by having each
>         usage 'subclass' the next/prev node pointers structure. 
>       * aren't as flexible and efficient as they might be.  e.g. you
>         often store a hashtable key+data pair where the data contains
>         the key, or it can be calculated from the data.  So you end up
>         wasting a pointer storing a duplicate of the key pointer.  Or
>         worse, where you store an integer as the data pointer which
>         has portability as well as type issues. 
>       * I could probably go on ...

Hey, what do you think about GRelation :-)  I searched far and wide
before I found code that used it...

> To put it bluntly, glib's data structures 'mostly suck', but they're
> there, and usually simple to use, so we use them sometimes.

Fair enough,

Yours,

Tom





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