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