From 635e53433d0900da27962506da2ac57f194efb20 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 7 Jul 2011 09:52:24 +0200 Subject: [PATCH] treeview: Add _gtk_rbtree_find_index() Uses the parity to do an O(log N) search for the nth element in the tree in display order of the treeview. --- gtk/gtkrbtree.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkrbtree.h | 4 ++++ 2 files changed, 54 insertions(+) diff --git a/gtk/gtkrbtree.c b/gtk/gtkrbtree.c index 27c9d84fe4..c8ff556043 100644 --- a/gtk/gtkrbtree.c +++ b/gtk/gtkrbtree.c @@ -1104,6 +1104,56 @@ _gtk_rbtree_find_offset (GtkRBTree *tree, return _gtk_rbtree_real_find_offset (tree, height, new_tree, new_node); } +gboolean +_gtk_rbtree_find_index (GtkRBTree *tree, + guint index, + GtkRBTree **new_tree, + GtkRBNode **new_node) +{ + GtkRBNode *tmp_node; + + g_assert (tree); + + tmp_node = tree->root; + while (tmp_node != tree->nil) + { + if (tmp_node->left->total_count > index) + { + tmp_node = tmp_node->left; + } + else if (tmp_node->total_count - tmp_node->right->total_count <= index) + { + index -= tmp_node->total_count - tmp_node->right->total_count; + tmp_node = tmp_node->right; + } + else + { + index -= tmp_node->left->total_count; + break; + } + } + if (tmp_node == tree->nil) + { + *new_tree = NULL; + *new_node = NULL; + return FALSE; + } + + if (index > 0) + { + g_assert (tmp_node->children); + + return _gtk_rbtree_find_index (tmp_node->children, + index - 1, + new_tree, + new_node); + } + + *new_tree = tree; + *new_node = tmp_node; + return TRUE; +} + void _gtk_rbtree_remove_node (GtkRBTree *tree, GtkRBNode *node) diff --git a/gtk/gtkrbtree.h b/gtk/gtkrbtree.h index 85b3dad60b..752fddc57c 100644 --- a/gtk/gtkrbtree.h +++ b/gtk/gtkrbtree.h @@ -135,6 +135,10 @@ gint _gtk_rbtree_node_find_offset (GtkRBTree *tree, GtkRBNode *node); gint _gtk_rbtree_node_find_parity (GtkRBTree *tree, GtkRBNode *node); +gboolean _gtk_rbtree_find_index (GtkRBTree *tree, + guint index, + GtkRBTree **new_tree, + GtkRBNode **new_node); gint _gtk_rbtree_find_offset (GtkRBTree *tree, gint offset, GtkRBTree **new_tree,