Fixed some minor typos in the documentation.
[platform/upstream/glib.git] / glib / gsequence.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3  * Soeren Sandmann (sandmann@daimi.au.dk)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "glib.h"
24 #include "galias.h"
25
26 typedef struct _GSequenceNode GSequenceNode;
27
28 struct _GSequence
29 {
30   GSequenceNode *       end_node;
31   GDestroyNotify        data_destroy_notify;
32   gboolean              access_prohibited;
33
34   /* The 'real_sequence' is used when temporary sequences are created
35    * to hold nodes that are being rearranged. The 'real_sequence' of such
36    * a temporary sequence points to the sequence that is actually being
37    * manipulated. The only reason we need this is so that when the
38    * sort/sort_changed/search_iter() functions call out to the application
39    * g_sequence_iter_get_sequence() will return the correct sequence.
40    */
41   GSequence *           real_sequence;
42 };
43
44 struct _GSequenceNode
45 {
46   gint                  n_nodes;
47   GSequenceNode *       parent;    
48   GSequenceNode *       left;
49   GSequenceNode *       right;
50   gpointer              data;   /* For the end node, this field points
51                                  * to the sequence
52                                  */
53 };
54
55 /*
56  * Declaration of GSequenceNode methods
57  */
58 static GSequenceNode *node_new           (gpointer                  data);
59 static GSequenceNode *node_get_first     (GSequenceNode            *node);
60 static GSequenceNode *node_get_last      (GSequenceNode            *node);
61 static GSequenceNode *node_get_prev      (GSequenceNode            *node);
62 static GSequenceNode *node_get_next      (GSequenceNode            *node);
63 static gint           node_get_pos       (GSequenceNode            *node);
64 static GSequenceNode *node_get_by_pos    (GSequenceNode            *node,
65                                           gint                      pos);
66 static GSequenceNode *node_find_closest  (GSequenceNode            *haystack,
67                                           GSequenceNode            *needle,
68                                           GSequenceNode            *end,
69                                           GSequenceIterCompareFunc  cmp,
70                                           gpointer                  user_data);
71 static gint           node_get_length    (GSequenceNode            *node);
72 static void           node_free          (GSequenceNode            *node,
73                                           GSequence                *seq);
74 static void           node_cut           (GSequenceNode            *split);
75 static void           node_insert_before (GSequenceNode            *node,
76                                           GSequenceNode            *new);
77 static void           node_unlink        (GSequenceNode            *node);
78 static void           node_join          (GSequenceNode            *left,
79                                           GSequenceNode            *right);
80 static void           node_insert_sorted (GSequenceNode            *node,
81                                           GSequenceNode            *new,
82                                           GSequenceNode            *end,
83                                           GSequenceIterCompareFunc  cmp_func,
84                                           gpointer                  cmp_data);
85
86
87 /*
88  * Various helper functions
89  */
90 static void
91 check_seq_access (GSequence *seq)
92 {
93   if (G_UNLIKELY (seq->access_prohibited))
94     {
95       g_warning ("Accessing a sequence while it is "
96                  "being sorted or searched is not allowed");
97     }
98 }
99
100 static GSequence *
101 get_sequence (GSequenceNode *node)
102 {
103   return (GSequence *)node_get_last (node)->data;
104 }
105
106 static void
107 check_iter_access (GSequenceIter *iter)
108 {
109   check_seq_access (get_sequence (iter));
110 }
111
112 static gboolean
113 is_end (GSequenceIter *iter)
114 {
115   GSequence *seq;
116
117   if (iter->right)
118     return FALSE;
119
120   if (!iter->parent)
121     return TRUE;
122
123   if (iter->parent->right != iter)
124     return FALSE;
125
126   seq = get_sequence (iter);
127
128   return seq->end_node == iter;
129 }
130
131 typedef struct
132 {
133   GCompareDataFunc  cmp_func;
134   gpointer          cmp_data;
135   GSequenceNode    *end_node;
136 } SortInfo;
137
138 /* This function compares two iters using a normal compare
139  * function and user_data passed in in a SortInfo struct
140  */
141 static gint
142 iter_compare (GSequenceIter *node1,
143               GSequenceIter *node2,
144               gpointer       data)
145 {
146   const SortInfo *info = data;
147   gint retval;
148   
149   if (node1 == info->end_node)
150     return 1;
151   
152   if (node2 == info->end_node)
153     return -1;
154   
155   retval = info->cmp_func (node1->data, node2->data, info->cmp_data);
156   
157   return retval;
158 }
159
160 /*
161  * Public API
162  */
163
164 /**
165  * g_sequence_new:
166  * @data_destroy: a #GDestroyNotify function, or %NULL
167  * 
168  * Creates a new GSequence. The @data_destroy function, if non-%NULL will
169  * be called on all items when the sequence is destroyed and on items that
170  * are removed from the sequence.
171  * 
172  * Return value: a new #GSequence
173  * 
174  * Since: 2.14
175  **/
176 GSequence *
177 g_sequence_new (GDestroyNotify data_destroy)
178 {
179   GSequence *seq = g_new (GSequence, 1);
180   seq->data_destroy_notify = data_destroy;
181   
182   seq->end_node = node_new (seq);
183   
184   seq->access_prohibited = FALSE;
185
186   seq->real_sequence = seq;
187   
188   return seq;
189 }
190
191 /**
192  * g_sequence_free:
193  * @seq: a #GSequence
194  * 
195  * Frees the memory allocated for @seq. If @seq has a data destroy 
196  * function associated with it, that function is called on all items in
197  * @seq.
198  * 
199  * Since: 2.14
200  **/
201 void
202 g_sequence_free (GSequence *seq)
203 {
204   g_return_if_fail (seq != NULL);
205   
206   check_seq_access (seq);
207   
208   node_free (seq->end_node, seq);
209   
210   g_free (seq);
211 }
212
213 /**
214  * g_sequence_foreach_range:
215  * @begin: a #GSequenceIter
216  * @end: a #GSequenceIter
217  * @func: a #GFunc
218  * @user_data: user data passed to @func
219  * 
220  * Calls @func for each item in the range (@begin, @end) passing
221  * @user_data to the function.
222  * 
223  * Since: 2.14
224  **/
225 void
226 g_sequence_foreach_range (GSequenceIter *begin,
227                           GSequenceIter *end,
228                           GFunc          func,
229                           gpointer       user_data)
230 {
231   GSequence *seq;
232   GSequenceIter *iter;
233   
234   g_return_if_fail (func != NULL);
235   g_return_if_fail (begin != NULL);
236   g_return_if_fail (end != NULL);
237   
238   seq = get_sequence (begin);
239   
240   seq->access_prohibited = TRUE;
241   
242   iter = begin;
243   while (iter != end)
244     {
245       GSequenceIter *next = node_get_next (iter);
246       
247       func (iter->data, user_data);
248       
249       iter = next;
250     }
251   
252   seq->access_prohibited = FALSE;
253 }
254
255 /**
256  * g_sequence_foreach:
257  * @seq: a #GSequence
258  * @func: the function to call for each item in @seq
259  * @user_data: user data passed to @func
260  * 
261  * Calls @func for each item in the sequence passing @user_data
262  * to the function.
263  * 
264  * Since: 2.14
265  **/
266 void
267 g_sequence_foreach (GSequence *seq,
268                     GFunc      func,
269                     gpointer   user_data)
270 {
271   GSequenceIter *begin, *end;
272   
273   check_seq_access (seq);
274   
275   begin = g_sequence_get_begin_iter (seq);
276   end   = g_sequence_get_end_iter (seq);
277   
278   g_sequence_foreach_range (begin, end, func, user_data);
279 }
280
281 /**
282  * g_sequence_range_get_midpoint:
283  * @begin: a #GSequenceIter
284  * @end: a #GSequenceIter
285  * 
286  * Finds an iterator somewhere in the range (@begin, @end). This
287  * iterator will be close to the middle of the range, but is not
288  * guaranteed to be <emphasis>exactly</emphasis> in the middle.
289  *
290  * The @begin and @end iterators must both point to the same sequence and
291  * @begin must come before or be equal to @end in the sequence.
292  * 
293  * Return value: A #GSequenceIter pointing somewhere in the
294  * (@begin, @end) range.
295  * 
296  * Since: 2.14
297  **/
298 GSequenceIter *
299 g_sequence_range_get_midpoint (GSequenceIter *begin,
300                                GSequenceIter *end)
301 {
302   int begin_pos, end_pos, mid_pos;
303   
304   g_return_val_if_fail (begin != NULL, NULL);
305   g_return_val_if_fail (end != NULL, NULL);
306   g_return_val_if_fail (get_sequence (begin) == get_sequence (end), NULL);
307   
308   begin_pos = node_get_pos (begin);
309   end_pos = node_get_pos (end);
310   
311   g_return_val_if_fail (end_pos >= begin_pos, NULL);
312   
313   mid_pos = begin_pos + (end_pos - begin_pos) / 2;
314   
315   return node_get_by_pos (begin, mid_pos);
316 }
317
318 /**
319  * g_sequence_iter_compare:
320  * @a: a #GSequenceIter
321  * @b: a #GSequenceIter
322  * 
323  * Returns a negative number if @a comes before @b, 0 if they are equal,
324  * and a positive number if @a comes after @b.
325  *
326  * The @a and @b iterators must point into the same sequence.
327  * 
328  * Return value: A negative number if @a comes before @b, 0 if they are
329  * equal, and a positive number if @a comes after @b.
330  * 
331  * Since: 2.14
332  **/
333 gint
334 g_sequence_iter_compare (GSequenceIter *a,
335                          GSequenceIter *b)
336 {
337   gint a_pos, b_pos;
338   
339   g_return_val_if_fail (a != NULL, 0);
340   g_return_val_if_fail (b != NULL, 0);
341   g_return_val_if_fail (get_sequence (a) == get_sequence (b), 0);
342   
343   check_iter_access (a);
344   check_iter_access (b);
345   
346   a_pos = node_get_pos (a);
347   b_pos = node_get_pos (b);
348   
349   if (a_pos == b_pos)
350     return 0;
351   else if (a_pos > b_pos)
352     return 1;
353   else
354     return -1;
355 }
356
357 /**
358  * g_sequence_append:
359  * @seq: a #GSequencePointer
360  * @data: the data for the new item
361  * 
362  * Adds a new item to the end of @seq.
363  * 
364  * Return value: an iterator pointing to the new item
365  * 
366  * Since: 2.14
367  **/
368 GSequenceIter *
369 g_sequence_append (GSequence *seq,
370                    gpointer   data)
371 {
372   GSequenceNode *node;
373   
374   g_return_val_if_fail (seq != NULL, NULL);
375   
376   check_seq_access (seq);
377   
378   node = node_new (data);
379   node_insert_before (seq->end_node, node);
380   
381   return node;
382 }
383
384 /**
385  * g_sequence_prepend:
386  * @seq: a #GSequence
387  * @data: the data for the new item
388  * 
389  * Adds a new item to the front of @seq
390  * 
391  * Return value: an iterator pointing to the new item
392  * 
393  * Since: 2.14
394  **/
395 GSequenceIter *
396 g_sequence_prepend (GSequence *seq,
397                     gpointer   data)
398 {
399   GSequenceNode *node, *first;
400   
401   g_return_val_if_fail (seq != NULL, NULL);
402   
403   check_seq_access (seq);
404   
405   node = node_new (data);
406   first = node_get_first (seq->end_node);
407   
408   node_insert_before (first, node);
409   
410   return node;
411 }
412
413 /**
414  * g_sequence_insert_before:
415  * @iter: a #GSequenceIter
416  * @data: the data for the new item
417  * 
418  * Inserts a new item just before the item pointed to by @iter.
419  * 
420  * Return value: an iterator pointing to the new item
421  * 
422  * Since: 2.14
423  **/
424 GSequenceIter *
425 g_sequence_insert_before (GSequenceIter *iter,
426                           gpointer       data)
427 {
428   GSequenceNode *node;
429   
430   g_return_val_if_fail (iter != NULL, NULL);
431   
432   check_iter_access (iter);
433   
434   node = node_new (data);
435   
436   node_insert_before (iter, node);
437   
438   return node;
439 }
440
441 /**
442  * g_sequence_remove:
443  * @iter: a #GSequenceIter
444  * 
445  * Removes the item pointed to by @iter. It is an error to pass the
446  * end iterator to this function.
447  *
448  * If the sequnce has a data destroy function associated with it, this
449  * function is called on the data for the removed item.
450  * 
451  * Since: 2.14
452  **/
453 void
454 g_sequence_remove (GSequenceIter *iter)
455 {
456   GSequence *seq;
457   
458   g_return_if_fail (iter != NULL);
459   g_return_if_fail (!is_end (iter));
460   
461   check_iter_access (iter);
462   
463   seq = get_sequence (iter); 
464   
465   node_unlink (iter);
466   node_free (iter, seq);
467 }
468
469 /**
470  * g_sequence_remove_range:
471  * @begin: a #GSequenceIter
472  * @end: a #GSequenceIter
473  * 
474  * Removes all items in the (@begin, @end) range.
475  *
476  * If the sequence has a data destroy function associated with it, this
477  * function is called on the data for the removed items.
478  * 
479  * Since: 2.14
480  **/
481 void
482 g_sequence_remove_range (GSequenceIter *begin,
483                          GSequenceIter *end)
484 {
485   g_return_if_fail (get_sequence (begin) == get_sequence (end));
486   
487   check_iter_access (begin);
488   check_iter_access (end);
489   
490   g_sequence_move_range (NULL, begin, end);
491 }
492
493 /**
494  * g_sequence_move_range:
495  * @dest: a #GSequenceIter
496  * @begin: a #GSequenceIter
497  * @end: a #GSequenceIter
498  * 
499  * Inserts the (@begin, @end) range at the destination pointed to by ptr.
500  * The @begin and @end iters must point into the same sequence. It is
501  * allowed for @dest to point to a different sequence than the one pointed
502  * into by @begin and @end.
503  * 
504  * If @dest is NULL, the range indicated by @begin and @end is
505  * removed from the sequence. If @dest iter points to a place within
506  * the (@begin, @end) range, the range does not move.
507  * 
508  * Since: 2.14
509  **/
510 void
511 g_sequence_move_range (GSequenceIter *dest,
512                        GSequenceIter *begin,
513                        GSequenceIter *end)
514 {
515   GSequence *src_seq;
516   GSequenceNode *first;
517   
518   g_return_if_fail (begin != NULL);
519   g_return_if_fail (end != NULL);
520   
521   check_iter_access (begin);
522   check_iter_access (end);
523   if (dest)
524     check_iter_access (dest);
525   
526   src_seq = get_sequence (begin);
527   
528   g_return_if_fail (src_seq == get_sequence (end));
529   
530   /* Dest points to begin or end? */
531   if (dest == begin || dest == end)
532     return;
533   
534   /* begin comes after end? */
535   if (g_sequence_iter_compare (begin, end) >= 0)
536     return;
537   
538   /* dest points somewhere in the (begin, end) range? */
539   if (dest && get_sequence (dest) == src_seq &&
540       g_sequence_iter_compare (dest, begin) > 0 &&
541       g_sequence_iter_compare (dest, end) < 0)
542     {
543       return;
544     }
545   
546   src_seq = get_sequence (begin);
547   
548   first = node_get_first (begin);
549   
550   node_cut (begin);
551   
552   node_cut (end);
553   
554   if (first != begin)
555     node_join (first, end);
556   
557   if (dest)
558     {
559       first = node_get_first (dest);
560       
561       node_cut (dest);
562       
563       node_join (begin, dest);
564       
565       if (dest != first)
566         node_join (first, begin);
567     }
568   else
569     {
570       node_free (begin, src_seq);
571     }
572 }
573
574 /**
575  * g_sequence_sort:
576  * @seq: a #GSequence
577  * @cmp_func: the #GCompareDataFunc used to sort @seq. This function is
578  *       passed two items of @seq and should return 0 if they are equal,
579  *       a negative value fi the first comes before the second, and a
580  *       positive value if the second comes before the first.
581  * @cmp_data: user data passed to @cmp_func
582  * 
583  * Sorts @seq using @cmp_func.
584  * 
585  * Since: 2.14
586  **/
587 void
588 g_sequence_sort (GSequence        *seq,
589                  GCompareDataFunc  cmp_func,
590                  gpointer          cmp_data)
591 {
592   SortInfo info = { cmp_func, cmp_data, seq->end_node };
593   
594   check_seq_access (seq);
595   
596   g_sequence_sort_iter (seq, iter_compare, &info);
597 }
598
599 /**
600  * g_sequence_insert_sorted:
601  * @seq: a #GSequence
602  * @data: the data to insert
603  * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
604  *     is called with two items of the @seq and @user_data. It should
605  *     return 0 if the items are equal, a negative value if the first
606  *     item comes before the second, and a positive value if the second
607  *     item comes before the first.
608  * @cmp_data: user data passed to @cmp_func.
609  *
610  * Inserts @data into @sequence using @func to determine the new position.
611  * The sequence must already be sorted according to @cmp_func; otherwise the
612  * new position of @data is undefined.
613  *
614  * Return value: a #GSequenceIter pointing to the new item.
615  * 
616  * Since: 2.14
617  **/
618 GSequenceIter *
619 g_sequence_insert_sorted (GSequence        *seq,
620                           gpointer          data,
621                           GCompareDataFunc  cmp_func,
622                           gpointer          cmp_data)
623 {
624   SortInfo info = { cmp_func, cmp_data, NULL };
625   
626   g_return_val_if_fail (seq != NULL, NULL);
627   g_return_val_if_fail (cmp_func != NULL, NULL);
628   
629   info.end_node = seq->end_node;
630   check_seq_access (seq);
631   
632   return g_sequence_insert_sorted_iter (seq, data, iter_compare, &info);
633 }
634
635 /**
636  * g_sequence_sort_changed:
637  * @iter: A #GSequenceIter
638  * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
639  *     is called with two items of the @seq and @user_data. It should
640  *     return 0 if the items are equal, a negative value if the first
641  *     item comes before the second, and a positive value if the second
642  *     item comes before the first.
643  * @cmp_data: user data passed to @cmp_func.
644  *
645  * Moves the data pointed to a new position as indicated by @cmp_func. This
646  * function should be called for items in a sequence already sorted according
647  * to @cmp_func whenever some aspect of an item changes so that @cmp_func
648  * may return different values for that item.
649  * 
650  * Since: 2.14
651  **/
652 void
653 g_sequence_sort_changed (GSequenceIter    *iter,
654                          GCompareDataFunc  cmp_func,
655                          gpointer          cmp_data)
656 {
657   SortInfo info = { cmp_func, cmp_data, NULL };
658   
659   g_return_if_fail (!is_end (iter));
660   
661   info.end_node = get_sequence (iter)->end_node;
662   check_iter_access (iter);
663   
664   g_sequence_sort_changed_iter (iter, iter_compare, &info);
665 }
666
667 /**
668  * g_sequence_search:
669  * @seq: a #GSequence
670  * @data: data for the new item
671  * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
672  *     is called with two items of the @seq and @user_data. It should
673  *     return 0 if the items are equal, a negative value if the first
674  *     item comes before the second, and a positive value if the second
675  *     item comes before the first.
676  * @cmp_data: user data passed to @cmp_func.
677  * 
678  * Returns an iterator pointing to the position where @data would
679  * be inserted according to @cmp_func and @cmp_data.
680  * 
681  * Return value: an #GSequenceIter pointing to the position where @data
682  * would have been inserted according to @cmp_func and @cmp_data.
683  * 
684  * Since: 2.14
685  **/
686 GSequenceIter *
687 g_sequence_search (GSequence        *seq,
688                    gpointer          data,
689                    GCompareDataFunc  cmp_func,
690                    gpointer          cmp_data)
691 {
692   SortInfo info = { cmp_func, cmp_data, NULL };
693   
694   g_return_val_if_fail (seq != NULL, NULL);
695   
696   info.end_node = seq->end_node;
697   check_seq_access (seq);
698   
699   return g_sequence_search_iter (seq, data, iter_compare, &info);
700 }
701
702 /**
703  * g_sequence_sort_iter:
704  * @seq: a #GSequence
705  * @cmp_func: the #GSequenceItercompare used to compare iterators in the
706  *     sequence. It is called with two iterators pointing into @seq. It should
707  *     return 0 if the iterators are equal, a negative value if the first
708  *     iterator comes before the second, and a positive value if the second
709  *     iterator comes before the first.
710  * @cmp_data: user data passed to @cmp_func
711  *
712  * Like g_sequence_sort(), but uses a #GSequenceIterCompareFunc instead
713  * of a GCompareDataFunc as the compare function
714  * 
715  * Since: 2.14
716  **/
717 void
718 g_sequence_sort_iter (GSequence                *seq,
719                       GSequenceIterCompareFunc  cmp_func,
720                       gpointer                  cmp_data)
721 {
722   GSequence *tmp;
723   GSequenceNode *begin, *end;
724   
725   g_return_if_fail (seq != NULL);
726   g_return_if_fail (cmp_func != NULL);
727   
728   check_seq_access (seq);
729   
730   begin = g_sequence_get_begin_iter (seq);
731   end   = g_sequence_get_end_iter (seq);
732   
733   tmp = g_sequence_new (NULL);
734   tmp->real_sequence = seq;
735   
736   g_sequence_move_range (g_sequence_get_begin_iter (tmp), begin, end);
737   
738   seq->access_prohibited = TRUE;
739   tmp->access_prohibited = TRUE;
740   
741   while (g_sequence_get_length (tmp) > 0)
742     {
743       GSequenceNode *node = g_sequence_get_begin_iter (tmp);
744       
745       node_insert_sorted (seq->end_node, node, seq->end_node,
746                           cmp_func, cmp_data);
747     }
748   
749   tmp->access_prohibited = FALSE;
750   seq->access_prohibited = FALSE;
751   
752   g_sequence_free (tmp);
753 }
754
755 /**
756  * g_sequence_sort_changed_iter:
757  * @iter: a #GSequenceIter
758  * @iter_cmp: the #GSequenceItercompare used to compare iterators in the
759  *     sequence. It is called with two iterators pointing into @seq. It should
760  *     return 0 if the iterators are equal, a negative value if the first
761  *     iterator comes before the second, and a positive value if the second
762  *     iterator comes before the first.
763  * @cmp_data: user data passed to @cmp_func
764  *
765  * Like g_sequence_sort_changed(), but uses
766  * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
767  * the compare function.
768  * 
769  * Since: 2.14
770  **/
771 void
772 g_sequence_sort_changed_iter (GSequenceIter            *iter,
773                               GSequenceIterCompareFunc  iter_cmp,
774                               gpointer                  cmp_data)
775 {
776   GSequence *seq, *tmp_seq;
777   GSequenceIter *next, *prev;
778
779   g_return_if_fail (iter != NULL);
780   g_return_if_fail (!is_end (iter));
781   g_return_if_fail (iter_cmp != NULL);
782   check_iter_access (iter);
783   
784   /* If one of the neighbours is equal to iter, then
785    * don't move it. This ensures that sort_changed() is
786    * a stable operation.
787    */
788   
789   next = node_get_next (iter);
790   prev = node_get_prev (iter);
791   
792   if (prev != iter && iter_cmp (prev, iter, cmp_data) == 0)
793     return;
794   
795   if (!is_end (next) && iter_cmp (next, iter, cmp_data) == 0)
796     return;
797   
798   seq = get_sequence (iter);
799   
800   seq->access_prohibited = TRUE;
801
802   tmp_seq = g_sequence_new (NULL);
803   tmp_seq->real_sequence = seq;
804   
805   node_unlink (iter);
806   node_insert_before (tmp_seq->end_node, iter);
807   
808   node_insert_sorted (seq->end_node, iter, seq->end_node,
809                       iter_cmp, cmp_data);
810
811   g_sequence_free (tmp_seq);
812   
813   seq->access_prohibited = FALSE;
814 }
815
816 /**
817  * g_sequence_insert_sorted_iter:
818  * @seq: a #GSequence
819  * @data: data for the new item
820  * @iter_cmp: the #GSequenceItercompare used to compare iterators in the
821  *     sequence. It is called with two iterators pointing into @seq. It should
822  *     return 0 if the iterators are equal, a negative value if the first
823  *     iterator comes before the second, and a positive value if the second
824  *     iterator comes before the first.
825  * @cmp_data: user data passed to @cmp_func
826  * 
827  * Like g_sequence_insert_sorted(), but uses
828  * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
829  * the compare function.
830  * 
831  * Return value: a #GSequenceIter pointing to the new item
832  * 
833  * Since: 2.14
834  **/
835 GSequenceIter *
836 g_sequence_insert_sorted_iter (GSequence                *seq,
837                                gpointer                  data,
838                                GSequenceIterCompareFunc  iter_cmp,
839                                gpointer                  cmp_data)
840 {
841   GSequenceNode *new_node;
842   GSequence *tmp_seq;
843
844   g_return_val_if_fail (seq != NULL, NULL);
845   g_return_val_if_fail (iter_cmp != NULL, NULL);
846   
847   check_seq_access (seq);
848
849   seq->access_prohibited = TRUE;
850   
851   /* Create a new temporary sequence and put the new node into
852    * that. The reason for this is that the user compare function
853    * will be called with the new node, and if it dereferences, 
854    * "is_end" will be called on it. But that will crash if the
855    * node is not actually in a sequence.
856    *
857    * node_insert_sorted() makes sure the node is unlinked before
858    * it is inserted.
859    *
860    * The reason we need the "iter" versions at all is that that
861    * is the only kind of compare functions GtkTreeView can use.
862    */
863   tmp_seq = g_sequence_new (NULL);
864   tmp_seq->real_sequence = seq;
865   
866   new_node = g_sequence_append (tmp_seq, data);
867   
868   node_insert_sorted (seq->end_node, new_node,
869                       seq->end_node, iter_cmp, cmp_data);
870   
871   g_sequence_free (tmp_seq);
872
873   seq->access_prohibited = FALSE;
874   
875   return new_node;
876 }
877
878 /**
879  * g_sequence_search_iter:
880  * @seq: a #GSequence
881  * @data: data for the new item
882  * @iter_cmp: the #GSequenceIterCompare function used to compare iterators
883  *     in the sequence. It is called with two iterators pointing into @seq.
884  *     It should return 0 if the iterators are equal, a negative value if the
885  *     first iterator comes before the second, and a positive value if the
886  *     second iterator comes before the first.
887  * @cmp_data: user data passed to @iter_cmp
888  *
889  * Like g_sequence_search(), but uses
890  * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
891  * the compare function.
892  * 
893  * Return value: a #GSequenceIter pointing to the position in @seq
894  * where @data would have been inserted according to @iter_cmp and @cmp_data.
895  * 
896  * Since: 2.14
897  **/
898 GSequenceIter *
899 g_sequence_search_iter (GSequence                *seq,
900                         gpointer                  data,
901                         GSequenceIterCompareFunc  iter_cmp,
902                         gpointer                  cmp_data)
903 {
904   GSequenceNode *node;
905   GSequenceNode *dummy;
906   GSequence *tmp_seq;
907   
908   g_return_val_if_fail (seq != NULL, NULL);
909   
910   check_seq_access (seq);
911   
912   seq->access_prohibited = TRUE;
913
914   tmp_seq = g_sequence_new (NULL);
915   tmp_seq->real_sequence = seq;
916   
917   dummy = g_sequence_append (tmp_seq, data);
918   
919   node = node_find_closest (seq->end_node, dummy,
920                             seq->end_node, iter_cmp, cmp_data);
921
922   g_sequence_free (tmp_seq);
923   
924   seq->access_prohibited = FALSE;
925   
926   return node;
927 }
928
929 /**
930  * g_sequence_iter_get_sequence:
931  * @iter: a #GSequenceIter
932  * 
933  * Returns the #GSequence that @iter points into.
934  * 
935  * Return value: the #GSequence that @iter points into.
936  * 
937  * Since: 2.14
938  **/
939 GSequence *
940 g_sequence_iter_get_sequence (GSequenceIter *iter)
941 {
942   GSequence *seq;
943   
944   g_return_val_if_fail (iter != NULL, NULL);
945
946   seq = get_sequence (iter);
947
948   /* For temporary sequences, this points to the sequence that
949    * is actually being manipulated
950    */
951   return seq->real_sequence;
952 }
953
954 /**
955  * g_sequence_get:
956  * @iter: a #GSequenceIter
957  * 
958  * Returns the data that @iter points to.
959  * 
960  * Return value: the data that @iter points to
961  * 
962  * Since: 2.14
963  **/
964 gpointer
965 g_sequence_get (GSequenceIter *iter)
966 {
967   g_return_val_if_fail (iter != NULL, NULL);
968   g_return_val_if_fail (!is_end (iter), NULL);
969   
970   return iter->data;
971 }
972
973 /**
974  * g_sequence_set:
975  * @iter: a #GSequenceIter
976  * @data: new data for the item
977  * 
978  * Changes the data for the item pointed to by @iter to be @data. If
979  * the sequence has a data destroy function associated with it, that
980  * function is called on the existing data that @iter pointed to.
981  * 
982  * Since: 2.14
983  **/
984 void
985 g_sequence_set (GSequenceIter *iter,
986                 gpointer       data)
987 {
988   GSequence *seq;
989   
990   g_return_if_fail (iter != NULL);
991   g_return_if_fail (!is_end (iter));
992   
993   seq = get_sequence (iter);
994   
995   /* If @data is identical to iter->data, it is destroyed
996    * here. This will work right in case of ref-counted objects. Also
997    * it is similar to what ghashtables do.
998    *
999    * For non-refcounted data it's a little less convenient, but
1000    * code relying on self-setting not destroying would be
1001    * pretty dubious anyway ...
1002    */
1003   
1004   if (seq->data_destroy_notify)
1005     seq->data_destroy_notify (iter->data);
1006   
1007   iter->data = data;
1008 }
1009
1010 /**
1011  * g_sequence_get_length:
1012  * @seq: a #GSequence
1013  * 
1014  * Returns the length of @seq
1015  * 
1016  * Return value: the length of @seq
1017  * 
1018  * Since: 2.14
1019  **/
1020 gint
1021 g_sequence_get_length (GSequence *seq)
1022 {
1023   return node_get_length (seq->end_node) - 1;
1024 }
1025
1026 /**
1027  * g_sequence_get_end_iter:
1028  * @seq: a #GSequence 
1029  * 
1030  * Returns the end iterator for @seg
1031  * 
1032  * Return value: the end iterator for @seq
1033  * 
1034  * Since: 2.14
1035  **/
1036 GSequenceIter *
1037 g_sequence_get_end_iter (GSequence *seq)
1038 {
1039   g_return_val_if_fail (seq != NULL, NULL);
1040   
1041   return seq->end_node;
1042 }
1043
1044 /**
1045  * g_sequence_get_begin_iter:
1046  * @seq: a #GSequence
1047  * 
1048  * Returns the begin iterator for @seq.
1049  * 
1050  * Return value: the begin iterator for @seq.
1051  * 
1052  * Since: 2.14
1053  **/
1054 GSequenceIter *
1055 g_sequence_get_begin_iter (GSequence *seq)
1056 {
1057   g_return_val_if_fail (seq != NULL, NULL);
1058
1059   return node_get_first (seq->end_node);
1060 }
1061
1062 static int
1063 clamp_position (GSequence *seq,
1064                 int        pos)
1065 {
1066   gint len = g_sequence_get_length (seq);
1067   
1068   if (pos > len || pos < 0)
1069     pos = len;
1070   
1071   return pos;
1072 }
1073
1074 /*
1075  * if pos > number of items or -1, will return end pointer
1076  */
1077 /**
1078  * g_sequence_get_iter_at_pos:
1079  * @seq: a #GSequence
1080  * @pos: a position in @seq, or -1 for the end.
1081  * 
1082  * Returns the iterator at position @pos. If @pos is negative or larger
1083  * than the number of items in @seq, the end iterator is returned.
1084  * 
1085  * Return value: The #GSequenceIter at position @pos
1086  * 
1087  * Since: 2.14
1088  **/
1089 GSequenceIter *
1090 g_sequence_get_iter_at_pos (GSequence *seq,
1091                             gint       pos)
1092 {
1093   g_return_val_if_fail (seq != NULL, NULL);
1094   
1095   pos = clamp_position (seq, pos);
1096   
1097   return node_get_by_pos (seq->end_node, pos);
1098 }
1099
1100 /**
1101  * g_sequence_move:
1102  * @src: a #GSequenceIter pointing to the item to move
1103  * @dest: a #GSequenceIter pointing to the position to which
1104  *        the item is moved.
1105  *
1106  * Moves the item pointed to by @src to the position indicated by @dest.
1107  * After calling this function @dest will point to the position immediately
1108  * after @src. It is allowed for @src and @dest to point into different
1109  * sequences.
1110  * 
1111  * Since: 2.14
1112  **/
1113 void
1114 g_sequence_move (GSequenceIter *src,
1115                  GSequenceIter *dest)
1116 {
1117   g_return_if_fail (src != NULL);
1118   g_return_if_fail (dest != NULL);
1119   g_return_if_fail (!is_end (src));
1120   
1121   if (src == dest)
1122     return;
1123   
1124   node_unlink (src);
1125   node_insert_before (dest, src);
1126 }
1127
1128 /* GSequenceIter */
1129
1130 /**
1131  * g_sequence_iter_is_end:
1132  * @iter: a #GSequenceIter
1133  * 
1134  * Returns whether @iter is the end iterator
1135  * 
1136  * Return value: Whether @iter is the end iterator.
1137  * 
1138  * Since: 2.14
1139  **/
1140 gboolean
1141 g_sequence_iter_is_end (GSequenceIter *iter)
1142 {
1143   g_return_val_if_fail (iter != NULL, FALSE);
1144   
1145   return is_end (iter);
1146 }
1147
1148 /**
1149  * g_sequence_iter_is_begin:
1150  * @iter: a #GSequenceIter
1151  * 
1152  * Returns whether @iter is the begin iterator
1153  * 
1154  * Return value: whether @iter is the begin iterator
1155  * 
1156  * Since: 2.14
1157  **/
1158 gboolean
1159 g_sequence_iter_is_begin (GSequenceIter *iter)
1160 {
1161   g_return_val_if_fail (iter != NULL, FALSE);
1162   
1163   return (node_get_prev (iter) == iter);
1164 }
1165
1166 /**
1167  * g_sequence_iter_get_position:
1168  * @iter: a #GSequenceIter
1169  * 
1170  * Returns the position of @iter
1171  * 
1172  * Return value: the position of @iter
1173  * 
1174  * Since: 2.14
1175  **/
1176 gint
1177 g_sequence_iter_get_position (GSequenceIter *iter)
1178 {
1179   g_return_val_if_fail (iter != NULL, -1);
1180   
1181   return node_get_pos (iter);
1182 }
1183
1184 /**
1185  * g_sequence_iter_next:
1186  * @iter: a #GSequenceIter
1187  * 
1188  * Returns an iterator pointing to the next position after @iter. If
1189  * @iter is the end iterator, the end iterator is returned.
1190  * 
1191  * Return value: a #GSequenceIter pointing to the next position after @iter.
1192  * 
1193  * Since: 2.14
1194  **/
1195 GSequenceIter *
1196 g_sequence_iter_next (GSequenceIter *iter)
1197 {
1198   g_return_val_if_fail (iter != NULL, NULL);
1199   
1200   return node_get_next (iter);
1201 }
1202
1203 /**
1204  * g_sequence_iter_prev:
1205  * @iter: a #GSequenceIter
1206  * 
1207  * Returns an iterator pointing to the previous position before @iter. If
1208  * @iter is the begin iterator, the begin iterator is returned.
1209  * 
1210  * Return value: a #GSequenceIter pointing to the previous position before
1211  * @iter.
1212  * 
1213  * Since: 2.14
1214  **/
1215 GSequenceIter *
1216 g_sequence_iter_prev (GSequenceIter *iter)
1217 {
1218   g_return_val_if_fail (iter != NULL, NULL);
1219   
1220   return node_get_prev (iter);
1221 }
1222
1223 /**
1224  * g_sequence_iter_move:
1225  * @iter: a #GSequenceIter
1226  * @delta: A positive or negative number indicating how many positions away
1227  *    from @iter the returned #GSequenceIter will be.
1228  *
1229  * Returns the #GSequenceIter which is @delta positions away from @iter.
1230  * If @iter is closer than -@delta positions to the beginning of the sequence,
1231  * the begin iterator is returned. If @iter is closer than @delta positions
1232  * to the end of the sequence, the end iterator is returned.
1233  *
1234  * Return value: a #GSequenceIter which is @delta positions away from @iter.
1235  * 
1236  * Since: 2.14
1237  **/
1238 GSequenceIter *
1239 g_sequence_iter_move (GSequenceIter *iter,
1240                       gint           delta)
1241 {
1242   gint new_pos;
1243   
1244   g_return_val_if_fail (iter != NULL, NULL);
1245   
1246   new_pos = node_get_pos (iter) + delta;
1247   
1248   new_pos = clamp_position (get_sequence (iter), new_pos);
1249   
1250   return node_get_by_pos (iter, new_pos);
1251 }
1252
1253 /**
1254  * g_sequence_swap:
1255  * @a: a #GSequenceIter
1256  * @b: a #GSequenceIter
1257  * 
1258  * Swaps the items pointed to by @a and @b. It is allowed for @a and @b
1259  * to point into difference sequences.
1260  * 
1261  * Since: 2.14
1262  **/
1263 void
1264 g_sequence_swap (GSequenceIter *a,
1265                  GSequenceIter *b)
1266 {
1267   GSequenceNode *leftmost, *rightmost, *rightmost_next;
1268   int a_pos, b_pos;
1269   
1270   g_return_if_fail (!g_sequence_iter_is_end (a));
1271   g_return_if_fail (!g_sequence_iter_is_end (b));
1272   
1273   if (a == b)
1274     return;
1275   
1276   a_pos = g_sequence_iter_get_position (a);
1277   b_pos = g_sequence_iter_get_position (b);
1278   
1279   if (a_pos > b_pos)
1280     {
1281       leftmost = b;
1282       rightmost = a;
1283     }
1284   else
1285     {
1286       leftmost = a;
1287       rightmost = b;
1288     }
1289   
1290   rightmost_next = node_get_next (rightmost);
1291   
1292   /* The situation is now like this:
1293    *
1294    *     ..., leftmost, ......., rightmost, rightmost_next, ...
1295    *
1296    */
1297   g_sequence_move (rightmost, leftmost);
1298   g_sequence_move (leftmost, rightmost_next);
1299 }
1300
1301 /*
1302  * Implementation of a treap
1303  *
1304  *
1305  */
1306 static guint
1307 get_priority (GSequenceNode *node)
1308 {
1309   guint key = GPOINTER_TO_UINT (node);
1310
1311   /* This hash function is based on one found on Thomas Wang's
1312    * web page at
1313    *
1314    *    http://www.concentric.net/~Ttwang/tech/inthash.htm
1315    *
1316    */
1317   key = (key << 15) - key - 1;
1318   key = key ^ (key >> 12);
1319   key = key + (key << 2);
1320   key = key ^ (key >> 4);
1321   key = key + (key << 3) + (key << 11);
1322   key = key ^ (key >> 16);
1323
1324   /* We rely on 0 being less than all other priorities */
1325   return key? key : 1;
1326 }
1327
1328 static GSequenceNode *
1329 find_root (GSequenceNode *node)
1330 {
1331   while (node->parent)
1332     node = node->parent;
1333   
1334   return node;
1335 }
1336
1337 static GSequenceNode *
1338 node_new (gpointer data)
1339 {
1340   GSequenceNode *node = g_slice_new0 (GSequenceNode);
1341   
1342   node->n_nodes = 1;
1343   node->data = data;
1344   node->left = NULL;
1345   node->right = NULL;
1346   node->parent = NULL;
1347   
1348   return node;
1349 }
1350
1351 static GSequenceNode *
1352 node_get_first (GSequenceNode *node)
1353 {
1354   node = find_root (node);
1355   
1356   while (node->left)
1357     node = node->left;
1358   
1359   return node;
1360 }
1361
1362 static GSequenceNode *
1363 node_get_last (GSequenceNode *node)
1364 {
1365   node = find_root (node);
1366   
1367   while (node->right)
1368     node = node->right;
1369   
1370   return node;
1371 }
1372
1373 #define NODE_LEFT_CHILD(n)  (((n)->parent) && ((n)->parent->left) == (n))
1374 #define NODE_RIGHT_CHILD(n) (((n)->parent) && ((n)->parent->right) == (n))
1375
1376 static GSequenceNode *
1377 node_get_next (GSequenceNode *node)
1378 {
1379   GSequenceNode *n = node;
1380
1381   if (n->right)
1382     {
1383       n = n->right;
1384       while (n->left)
1385         n = n->left;
1386     }
1387   else
1388     {
1389       while (NODE_RIGHT_CHILD (n))
1390         n = n->parent;
1391       
1392       if (n->parent)
1393         n = n->parent;
1394       else
1395         n = node;
1396     }
1397   
1398   return n;
1399 }
1400
1401 static GSequenceNode *
1402 node_get_prev (GSequenceNode *node)
1403 {
1404   GSequenceNode *n = node;
1405   
1406   if (n->left)
1407     {
1408       n = n->left;
1409       while (n->right)
1410         n = n->right;
1411     }
1412   else
1413     {
1414       while (NODE_LEFT_CHILD (n))
1415         n = n->parent;
1416       
1417       if (n->parent)
1418         n = n->parent;
1419       else
1420         n = node;
1421     }
1422   
1423   return n;
1424 }
1425
1426 #define N_NODES(n) ((n)? (n)->n_nodes : 0)
1427
1428 static gint
1429 node_get_pos (GSequenceNode *node)
1430 {
1431   int n_smaller = 0;
1432   
1433   if (node->left)
1434     n_smaller = node->left->n_nodes;
1435   
1436   while (node)
1437     {
1438       if (NODE_RIGHT_CHILD (node))
1439         n_smaller += N_NODES (node->parent->left) + 1;
1440       
1441       node = node->parent;
1442     }
1443   
1444   return n_smaller;
1445 }
1446
1447 static GSequenceNode *
1448 node_get_by_pos (GSequenceNode *node,
1449                  gint           pos)
1450 {
1451   int i;
1452   
1453   node = find_root (node);
1454   
1455   while ((i = N_NODES (node->left)) != pos)
1456     {
1457       if (i < pos)
1458         {
1459           node = node->right;
1460           pos -= (i + 1);
1461         }
1462       else
1463         {
1464           node = node->left;
1465         }
1466     }
1467   
1468   return node;
1469 }
1470
1471 static GSequenceNode *
1472 node_find_closest (GSequenceNode            *haystack,
1473                    GSequenceNode            *needle,
1474                    GSequenceNode            *end,
1475                    GSequenceIterCompareFunc  iter_cmp,
1476                    gpointer                  cmp_data)
1477 {
1478   GSequenceNode *best;
1479   gint c;
1480   
1481   haystack = find_root (haystack);
1482   
1483   do
1484     {
1485       best = haystack;
1486       
1487       /* iter_cmp can't be passed the end node, since the function may
1488        * be user-supplied
1489        */
1490       if (haystack == end)
1491         c = 1;
1492       else
1493         c = iter_cmp (haystack, needle, cmp_data);
1494       
1495       /* In the following we don't break even if c == 0. Instaed we go on
1496        * searching along the 'bigger' nodes, so that we find the last one
1497        * that is equal to the needle.
1498        */
1499       if (c > 0)
1500         haystack = haystack->left;
1501       else
1502         haystack = haystack->right;
1503     }
1504   while (haystack != NULL);
1505   
1506   /* If the best node is smaller or equal to the data, then move one step
1507    * to the right to make sure the best one is strictly bigger than the data
1508    */
1509   if (best != end && c <= 0)
1510     best = node_get_next (best);
1511   
1512   return best;
1513 }
1514
1515 static gint
1516 node_get_length    (GSequenceNode            *node)
1517 {
1518   node = find_root (node);
1519   
1520   return node->n_nodes;
1521 }
1522
1523 static void
1524 real_node_free (GSequenceNode *node,
1525                 GSequence     *seq)
1526 {
1527   if (node)
1528     {
1529       real_node_free (node->left, seq);
1530       real_node_free (node->right, seq);
1531       
1532       if (seq && seq->data_destroy_notify && node != seq->end_node)
1533         seq->data_destroy_notify (node->data);
1534       
1535       g_slice_free (GSequenceNode, node);
1536     }
1537 }
1538
1539 static void
1540 node_free (GSequenceNode *node,
1541            GSequence *seq)
1542 {
1543   node = find_root (node);
1544   
1545   real_node_free (node, seq);
1546 }
1547
1548 static void
1549 node_update_fields (GSequenceNode *node)
1550 {
1551   int n_nodes = 1;
1552   
1553   n_nodes += N_NODES (node->left);
1554   n_nodes += N_NODES (node->right);
1555   
1556   node->n_nodes = n_nodes;
1557 }
1558
1559 static void
1560 node_rotate (GSequenceNode *node)
1561 {
1562   GSequenceNode *tmp, *old;
1563   
1564   g_assert (node->parent);
1565   g_assert (node->parent != node);
1566   
1567   if (NODE_LEFT_CHILD (node))
1568     {
1569       /* rotate right */
1570       tmp = node->right;
1571   
1572       node->right = node->parent;
1573       node->parent = node->parent->parent;
1574       if (node->parent)
1575         {
1576           if (node->parent->left == node->right)
1577             node->parent->left = node;
1578           else
1579             node->parent->right = node;
1580         }
1581   
1582       g_assert (node->right);
1583   
1584       node->right->parent = node;
1585       node->right->left = tmp;
1586   
1587       if (node->right->left)
1588         node->right->left->parent = node->right;
1589       
1590       old = node->right;
1591     }
1592   else
1593     {
1594       /* rotate left */
1595       tmp = node->left;
1596
1597       node->left = node->parent;
1598       node->parent = node->parent->parent;
1599       if (node->parent)
1600         {
1601           if (node->parent->right == node->left)
1602             node->parent->right = node;
1603           else
1604             node->parent->left = node;
1605         }
1606   
1607       g_assert (node->left);
1608   
1609       node->left->parent = node;
1610       node->left->right = tmp;
1611   
1612       if (node->left->right)
1613         node->left->right->parent = node->left;
1614   
1615       old = node->left;
1616     }
1617   
1618   node_update_fields (old);
1619   node_update_fields (node);
1620 }
1621
1622 static void
1623 node_update_fields_deep (GSequenceNode *node)
1624 {
1625   if (node)
1626     {
1627       node_update_fields (node);
1628       
1629       node_update_fields_deep (node->parent);
1630     }
1631 }
1632
1633 static void
1634 rotate_down (GSequenceNode *node,
1635              guint          priority)
1636 {
1637   guint left, right;
1638   
1639   left = node->left ? get_priority (node->left)  : 0;
1640   right = node->right ? get_priority (node->right) : 0;
1641   
1642   while (priority < left || priority < right)
1643     {
1644       if (left > right)
1645         node_rotate (node->left);
1646       else
1647         node_rotate (node->right);
1648   
1649       left = node->left ? get_priority (node->left)  : 0;
1650       right = node->right ? get_priority (node->right) : 0;
1651     }
1652 }
1653
1654 static void
1655 node_cut (GSequenceNode *node)
1656 {
1657   while (node->parent)
1658     node_rotate (node);
1659   
1660   if (node->left)
1661     node->left->parent = NULL;
1662   
1663   node->left = NULL;
1664   node_update_fields (node);
1665   
1666   rotate_down (node, get_priority (node));
1667 }
1668
1669 static void
1670 node_join (GSequenceNode *left,
1671            GSequenceNode *right)
1672 {
1673   GSequenceNode *fake = node_new (NULL);
1674       
1675   fake->left = find_root (left);
1676   fake->right = find_root (right);
1677   fake->left->parent = fake;
1678   fake->right->parent = fake;
1679       
1680   node_update_fields (fake);
1681   
1682   node_unlink (fake);
1683   
1684   node_free (fake, NULL);
1685 }
1686
1687 static void
1688 node_insert_before (GSequenceNode *node,
1689                     GSequenceNode *new)
1690 {
1691   new->left = node->left;
1692   if (new->left)
1693     new->left->parent = new;
1694   
1695   new->parent = node;
1696   node->left = new;
1697   
1698   node_update_fields_deep (new);
1699   
1700   while (new->parent && get_priority (new) > get_priority (new->parent))
1701     node_rotate (new);
1702   
1703   rotate_down (new, get_priority (new));
1704 }
1705
1706 static void
1707 node_unlink (GSequenceNode *node)
1708 {
1709   rotate_down (node, 0);
1710   
1711   if (NODE_RIGHT_CHILD (node))
1712     node->parent->right = NULL;
1713   else if (NODE_LEFT_CHILD (node))
1714     node->parent->left = NULL;
1715   
1716   if (node->parent)
1717     node_update_fields_deep (node->parent);
1718   
1719   node->parent = NULL;
1720 }
1721
1722 static void
1723 node_insert_sorted (GSequenceNode            *node,
1724                     GSequenceNode            *new,
1725                     GSequenceNode            *end,
1726                     GSequenceIterCompareFunc  iter_cmp,
1727                     gpointer                  cmp_data)
1728 {
1729   GSequenceNode *closest;
1730   
1731   closest = node_find_closest (node, new, end, iter_cmp, cmp_data);
1732   
1733   node_unlink (new);
1734   
1735   node_insert_before (closest, new);
1736 }
1737
1738
1739 #define __G_SEQUENCE_C__
1740 #include "galiasdef.c"