Branch: refs/heads/master Author: Dimitar Zhekov dimitar.zhekov@gmail.com Committer: Dimitar Zhekov dimitar.zhekov@gmail.com Date: Fri, 19 Apr 2013 17:26:10 UTC Commit: 6c10372ae405e7ec3b27ee9e1a8213c777577d55 https://github.com/geany/geany-plugins/commit/6c10372ae405e7ec3b27ee9e1a8213...
Log Message: ----------- scope - typedef _AElem fix, added scptreestore.html
Modified Paths: -------------- scope/src/store/scptreestore.c scope/src/store/scptreestore.html
Modified: scope/src/store/scptreestore.c 4 files changed, 2 insertions(+), 2 deletions(-) =================================================================== @@ -44,12 +44,12 @@
typedef struct _AElem AElem;
-typedef struct _AElem +struct _AElem { AElem *parent; GPtrArray *children; ScpTreeData data[1]; -} AElem; +};
struct _ScpTreeStorePrivate {
Modified: scope/src/store/scptreestore.html 655 files changed, 655 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,655 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>ScpTreeStore</title> + <style type="text/css"> + .tab { padding-left:2em; } + </style> +</head> + +<body> + +<div><a href="#description">Description</a> <b>--</b> <a href="#synopsis">Synopsis</a> +<b>--</b> <a href="#properties">Properties</a> <b>--</b> <a href="#notes">Notes</a> <b>--</b> +<a href="#speed">Speed</a> <b>--</b> <a href="#bugs">Bugs</a> <b>--</b> <a href="#copyright"> +Copyright</a></div> + +<h2>ScpTreeStore</h2> + +<p>ScpTreeStore - an array-based GtkTreeStore/GtkListStore like object.</p> + +<hr> + +<h3><a name="description">Description</a></h3> + +<p>ScpTreeStore is a GtkTreeStore/GtkListStore object, based entitely on arrays. In +particular:</p> + +<ul> +<li>The column values for a row are stored in a C array</li> +<li>The column sort headers are stored in a C array</li> +<li>The rows are stored in GPtrArray-s.</li> +</ul> + +<p>Using arrays for the column headers and row data would probably be beneficial for +GtkTreeStore and GtkListStore too, leading to faster and smaller code.</p> + +<p>ScpTreeStore implements GtkTreeModel, GtkTreeDragSource, GtkTreeDragDest, GtkTreeSortable +and GtkBuildable. The functions that implement these interfaces are public, so you can invoke +them directly, without type-casting the store an interface (except for the GtkBuildable +functions, which are never invoked directly).</p> + +<hr> + +<h3><a name="synopsis">Synopsis</a></h3> + +<p>The functions identical to their GtkTreeStore or interface counterparts, as well as the +obvious funtions and macros, are listed without descriptions.</p> + +<p>The GtkTreeStore behviour described below applies to GtkListStore too (where applicable). +</p> + +<p>#include <gtk/gtk.h><br> +#include "scptreestore.h"</p> + +<p>/* Store */<br> +ScpTreeStore *<a href="scp_tree_store_new">scp_tree_store_new</a>(gboolean sublevels, gint +n_columns, ...);<br> +ScpTreeStore *<a href="scp_tree_store_newv">scp_tree_store_newv</a>(gboolean sublevels, gint +n_columns, GType *types);<br> +gboolean scp_tree_store_set_column_types(ScpTreeStore *store, gint n_columns, GType *types);<br> +#define scp_tree_store_set_utf8_collate(store, utf8_collate) +void scp_tree_store_set_valuesv(ScpTreeStore *store, GtkTreeIter *iter, gint *columns, GValue +*values, gint n_values);<br> +void scp_tree_store_set_value(ScpTreeStore *store, GtkTreeIter *iter, gint column, GValue +*value);<br> +void scp_tree_store_set_valist(ScpTreeStore *store, GtkTreeIter *iter, va_list ap);<br> +void scp_tree_store_set(ScpTreeStore *store, GtkTreeIter *iter, ...);<br> +gboolean <a href="#scp_tree_store_remove">scp_tree_store_remove</a>(ScpTreeStore *store, +GtkTreeIter *iter);<br> +void <a href="scp_tree_store_insert">scp_tree_store_insert</a>(ScpTreeStore *store, GtkTreeIter +*iter, GtkTreeIter *parent, gint position);<br> +#define scp_tree_store_prepend(store, iter, parent)<br> +#define scp_tree_store_append(store, iter, parent)<br> +void scp_tree_store_insert_with_valuesv(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*parent, gint position, gint *columns, GValue *values, gint n_values);<br> +#define scp_tree_store_prepend_with_valuesv(store, iter, parent, columns, values, n_values)<br> +#define scp_tree_store_append_with_valuesv(store, iter, parent, columns, values, n_values)<br> +void scp_tree_store_insert_with_valist(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*parent, gint position, va_list ap);<br> +#define scp_tree_store_prepend_with_valist(store, iter, parent, ap)<br> +#define scp_tree_store_append_with_valist(store, iter, parent, ap)<br> +void scp_tree_store_insert_with_values(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*parent, gint position, ...);<br> +#define scp_tree_store_prepend_with_values(store, iter, parent, ...)<br> +#define scp_tree_store_append_with_values(store, iter, parent, ...)<br> +void <a href="scp_tree_store_get_valist">scp_tree_store_get_valist</a>(ScpTreeStore *store, +GtkTreeIter *iter, va_list var_args);<br> +void <a href="scp_tree_store_get">scp_tree_store_get</a>(ScpTreeStore *store, GtkTreeIter +*iter, ...);<br> +gboolean scp_tree_store_is_ancestor(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*descendant);<br> +gint scp_tree_store_iter_depth(ScpTreeStore *store, GtkTreeIter *iter);<br> +void <a href="scp_tree_store_clear_children">scp_tree_store_clear_children</a>(ScpTreeStore +*store, GtkTreeIter *parent, gboolean emit_subsignals);<br> +#define <a href="scp_tree_store_clear">scp_tree_store_clear(store)</a><br> +gboolean scp_tree_store_iter_is_valid(ScpTreeStore *store, GtkTreeIter *iter);<br> +void scp_tree_store_reorder(ScpTreeStore *store, GtkTreeIter *parent, gint *new_order);<br> +void scp_tree_store_swap(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b);<br> +void <a href="#scp_tree_store_move">scp_tree_store_move</a>(ScpTreeStore *store, GtkTreeIter +*iter, gint position);<br> +</p> + +<p>/* Model */<br> +GtkTreeModelFlags scp_tree_store_get_flags(ScpTreeStore *store);<br> +gint scp_tree_store_get_n_columns(ScpTreeStore *store);<br> +GType scp_tree_store_get_column_type(ScpTreeStore *store, gint index);<br> +gboolean scp_tree_store_get_iter(ScpTreeStore *store, GtkTreeIter *iter, GtkTreePath *path);<br> +GtkTreePath *scp_tree_store_get_path(ScpTreeStore *store, GtkTreeIter *iter);<br> +void scp_tree_store_get_value(ScpTreeStore *model, GtkTreeIter *iter, gint column, GValue +*value);<br> +gboolean scp_tree_store_iter_next(ScpTreeStore *store, GtkTreeIter *iter);<br> +gboolean <a href="#scp_tree_store_iter_previous">scp_tree_store_iter_previous</a>(ScpTreeStore +*store, GtkTreeIter *iter);<br> +gboolean scp_tree_store_iter_children(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*parent);<br> +gboolean scp_tree_store_iter_has_child(ScpTreeStore *store, GtkTreeIter *iter);<br> +gint scp_tree_store_iter_n_children(ScpTreeStore *store, GtkTreeIter *iter);<br> +gboolean scp_tree_store_iter_nth_child(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*parent, gint n);<br> +#define scp_tree_store_get_iter_first(store, iter)<br> +gboolean scp_tree_store_iter_parent(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter +*child);<br> +</p> + +<p>/* DND */<br> +gboolean scp_tree_store_row_draggable(ScpTreeStore *store, GtkTreePath *path);<br> +gboolean scp_tree_store_drag_data_delete(ScpTreeStore *store, GtkTreePath *path);<br> +gboolean scp_tree_store_drag_data_get(ScpTreeStore *store, GtkTreePath *path, GtkSelectionData +*selection_data);<br> +gboolean scp_tree_store_drag_data_received(ScpTreeStore *store, GtkTreePath *dest, +GtkSelectionData *selection_data);<br> +gboolean scp_tree_store_row_drop_possible(ScpTreeStore *store, GtkTreePath *dest_path, +GtkSelectionData *selection_data);<br> +</p> + +<p>/* Sortable */<br> +gboolean scp_tree_store_get_sort_column_id(ScpTreeStore *store, gint *sort_column_id, +GtkSortType *order);<br> +void scp_tree_store_set_sort_column_id(ScpTreeStore *store, gint sort_column_id, GtkSortType +order);<br> +void scp_tree_store_set_sort_func(ScpTreeStore *store, gint sort_column_id, +GtkTreeIterCompareFunc func, gpointer data, GDestroyNotify destroy);<br> +void scp_tree_store_set_default_sort_func(ScpTreeStore *store, GtkTreeIterCompareFunc func, +gpointer data, GDestroyNotify destroy);<br> +gboolean scp_tree_store_has_default_sort_func(ScpTreeStore *store);<br> +</p> + +<p>/* Extra */<br> +void <a href="scp_tree_store_set_allocation">scp_tree_store_set_allocation</a>(ScpTreeStore +*store, guint toplevel_reserved, guint sublevel_reserved, gboolean sublevel_discard);<br> +gint <a href="#scp_tree_store_compare_func">scp_tree_store_compare_func</a>(ScpTreeStore *store, +GtkTreeIter *a, GtkTreeIter *b, gpointer data);<br> +gboolean <a href="#scp_tree_store_iter_seek">scp_tree_store_iter_seek</a>(ScpTreeStore *store, +GtkTreeIter *iter, gint position);<br> +gint scp_tree_store_iter_tell(ScpTreeStore *store, GtkTreeIter *iter);<br> +gboolean <a href="#scp_tree_store_search">scp_tree_store_search</a>(ScpTreeStore *store, +gboolean sublevels, gboolean linear_order, GtkTreeIter *iter, GtkTreeIter *parent, gint column, +...); +</p> + +<hr> + +<h3><a name="scp_tree_store_new">scp_tree_store_new()</a><br> +<a name="scp_tree_store_newv">scp_tree_store_newv()</a></h3> + +<p><b>ScpTreeStore *scp_tree_store_new(gboolean sublevels, gint n_columns, ...);<br> +ScpTreeStore *scp_tree_store_newv(gboolean sublevels, gint n_columns, GType *types);</b></p> + +<div>The sublevels parameter determines whether ScpTreeStore behaves as GtkTreeStore or +GtkListStore:</div> +<div class="tab">sublevels = <tt>TRUE</tt>: tree-like structure<br> +sublevels = <tt>FALSE</tt>: list-like structure.</div><br> + +<hr> + +<h3><a name="scp_tree_store_insert">scp_tree_store_insert()</a></h3> + +<p><b>void scp_tree_store_insert(ScpTreeStore *store, GtkTreeIter *iter, GtkTreeIter *parent, +gint position);</b></p> + +<p>position must be between -1 and N, where N is the number of rows at that level. +GtkTreeStore allows position > N and treats it as N (i.e. appends). To be precise, it +simply walks it's row-list either until position is reached or there are no more rows.</p> + +<p>If you insert a row in a sorted GtkTreeStore, and do not set a value for the sort column +(or for any column, if a non-standard sort function is being used), the row will remain where +you inserted it, possibly breaking the sort order. ScpTreeStore will sort such rows if needed. +</p> + +<p>When a row is being sorted as a result of an insert_with or set operation, GtkTreeStore +uses linear search, so this row always end up before the first row equal to it, if any. +ScpTreeStore uses binary search, and "If two iters compare as equal, their order in the sorted +model is undefined", as stated in the GtkTreeSortable documentation.</p> + +<hr> + +<h3><a name="scp_tree_store_remove">scp_tree_store_remove()</a></h3> + +<p><b>void scp_tree_store_remove(ScpTreeStore *store, GtkTreeIter *iter);</b></p> + +<p>GtkTreeStore removes the children of iter (if any) from first to last, while ScpTreeStore +removes them from last to first. The GTK+ documentation does not specify any particular order. +</p> + +<hr> + +<h3><a name="scp_tree_store_get_valist">scp_tree_store_get_valist()</a><br> +<a name="scp_tree_store_get">scp_tree_store_get()</a></h3> + +<p><b>void scp_tree_store_get_valist(ScpTreeStore *store, GtkTreeIter *iter, va_list +var_args);<br> +void scp_tree_store_get(ScpTreeStore *store, GtkTreeIter *iter, ...);</b></p> + +<p>Unlike the similar GtkTreeModel functions, these do not copy the strings or reference the +objects/boxeds, so the return values for these types (a) need not be freed/unreferenced, and +(b) may become invalid if the row is removed.</p> + +<hr> + +<h3><a name="scp_tree_store_clear_children">scp_tree_store_clear_children()</a></h3> + +<p><b>void scp_tree_store_clear_children(ScpTreeStore *store, GtkTreeIter *parent, gboolean +emit_subsignals);</b></p> + +<div>Removes all rows under parent, from last to first.</div> +<div class="tab">emit_subsignals = <tt>FALSE</tt>: emit "row-removed" signals only +for the rows directly under parent<br> +emit_subsignals = <tt>TRUE</tt>: emit "row-removed" signals for all removed rows<br> +parent = <tt>NULL</tt>: remove the top-level rows.</div><br> + +<hr> + +<h3><a name="scp_tree_store_clear">scp_tree_store_clear()</a></h3> + +<p><b>#define scp_tree_store_clear(store)</b></p> + +<p>gtk_tree_store_clear() emits "row-removed" signals not only for the top-level +rows, but for their all their children as well. ScpTreeStore follows that behaviour. Clearing +the store with scp_tree_store_clear_children(store, NULL, FALSE) is faster, though not +significantly.</p> + +<p>GtkTreeStore removes the rows from first to last, while ScpTreeStore removes them from last +to first. The GTK+ documentation does not specify any particular order.</p> + +<hr> + +<h3><a name="void scp_tree_store_move">void scp_tree_store_move()</a></h3> + +<p><b>void scp_tree_store_move(ScpTreeStore *store, GtkTreeIter *iter, gint position);</b></p> + +<div>Moves the row pointed by iter to a new position in the same level.</div> +<div class="tab">position = <tt>-1</tt>: move row to the last position.</div><br> + +<hr> + +<h3><a name="scp_tree_store_iter_previous">scp_tree_store_iter_previous()</a></h3> + +<p><b>gboolean scp_tree_store_iter_previous(ScpTreeStore *store, GtkTreeIter *iter);</b></p> + +<p>gtk_tree_model_iter_previous() requires gtk+ 3.0.0 or later; scp_tree_model_iter_previous() +does not.</p> + +<hr> + +<h3><a name="scp_tree_store_set_allocation">scp_tree_store_set_allocation()</a></h3> + +<p><b>void scp_tree_store_set_reserved(ScpTreeStore *store, guint toplevel_reserved, guint +sublevel_reserved, gboolean sublevel_discard);</b></p> + +<div>Sets the "toplevel-reserved", "sublevel-reserved" and +"sublevel_discard" <a href="#properties">properties</a>.</div> +<div class="tab"> toplevel_reserved = <tt>0</tt>: "toplevel-reserved" will not be +set (the default is 0 anyway).</div><br> + +<hr> + +<h3><a name="scp_tree_store_set_utf8_collate">scp_tree_store_set_utf8_collate()</a></h3> + +<p><b>void scp_tree_store_set_utf8_collate(ScpTreeStore *store, gint column, gboolean +collate);</b></p> + +<div>Normally, all stores compare strings with g_utf8_collate(), which is linguistically +correct, but awfully slow. With the gtk+ stores, you can create a separate column with the +string keys if needed, and write a small compare function that does g_strcmp0(). The side +effects are that when a store is sorted by a non-standard function, setting the value of any +column causes a check if the row is properly sorted, and ScpTreeStore's binary search can not +be used.</div> +<div class="tab">collate = <tt>TRUE</tt>: use g_utf8_collate() to compare strings, should only +be used with string columns<br> +collate = <tt>FALSE</tt>: use g_strcmp0() to compare strings, no side effects.</div> + +<hr> + +<h3><a name="scp_tree_store_compare_func">scp_tree_store_compare_func()</a></h3> + +<p><b>gint scp_tree_store_compare_func(ScpTreeStore *store, GtkTreeIter *a, GtkTreeIter *b, +gpointer data);</b></p> + +<div>The default ScpTreeStore data comparision function for columns >= 0.</div> +<div class="tab">data = <tt>GINT_TO_POINTER(column_to_compare)</tt></div> +<p>May NOT be used with GtkTreeStore and GtkListStore.<br> +Compatible with and type-castable to GtkTreeIterCompareFunc.</p> + +<hr> + +<h3><a name="scp_tree_store_iter_seek">scp_tree_store_iter_seek()</a></h3> + +<p><b>gboolean scp_tree_store_iter_seek(ScpTreeStore *store, GtkTreeIter *iter, gint +position);</b></p> + +<div>Seek to row at position in the same level.</div> +<div class="tab">position = -1: seek to the last row.</div><br> + +<hr> + +<h3><a name="scp_tree_store_search">scp_tree_store_search()</a></h3> + +<p><b>gboolean scp_tree_store_search(ScpTreeStore *store, gboolean sublevels, gboolean +linear_order, GtkTreeIter *iter, GtkTreeIter *parent, gint column, ...);</b></p> + +<div>Search the rows under parent for one whose column data matches a value.</div> +<div class="tab">sublevels = <tt>FALSE</tt>: search only the rows directly under parent<br> +sublevels = <tt>TRUE</tt>: search all children<br> +linear_order: always return the first match<br> +parent = <tt>NULL</tt>: search the top-level rows<br> +...: value to compare with, must match the column type.</div> +<p>If column is the current sort column, it's compare function is the default one, and +linear_order is <tt>FALSE</tt>, binary search will be used. Aside from that, the column +compare function is ignored, because it requires an iterator, not a value. For string columns, +utf8_collate is taken into account.</p> + +<hr> + +<h3><a name="properties">Properties</a></h3> + +<p>"sublevels" (gboolean, read/construct only write) - whether the store supports +sublevels.</p> + +<p>"toplevel-reserved" (gint, read/write) - number of pointers to preallocate for +the top-level array. Default = <tt>0</tt>, GPtrArray allocates minimum <tt>16</tt>.</p> + +<p>"sublevel-reserved" (gint, read/write) - number of pointers to preallocate the +sublevel arrays. Default = <tt>0</tt>, GPtrArray allocates minimum <tt>16</tt>.</p> + +<p>"sublevel-discard" (gboolean, read/write) - whether to discard a sublevel array +when the last row from that level is removed. Default = <tt>FALSE</tt>.</p> + +<p>The arrays are allocated when the first row at that level is being inserted. Setting +"-reserved" has no effect on any currently allocated arrays. The top-level array is +discarded only when the store is finalized. Thus, setting "toplevel-reserved" after +at least row was inserted in the store has no effect.</p> + +<h3><a name="notes">Notes</a></h3> + +<h3>Non-persistent iterators</h3> + +<p>ScpTreeStore's iterators are non-persistent - that is, each operation which changes the +rows order may affect the iterators at that level. More specifically, the iterators work like +array indexes: for you have an iter_a for the 5th row, and remove the 3rd row, iter_a will now +point to the new 5th row (former 6th), or will become invalid, if there were 5 rows. Using +invalid iterators may generate warning messages, or simply crash the application (that applies +to GtkTreeStore as well).</p> + +<p>Obviously, appending to an <u>un</u>sorted store will not affect the existing iterators, +and you can predict the effects of all other operations - even for sorted stores, using +scp_tree_store_tell(). But it's easy to make mistakes, so if you need a persistent reference +to a row, it's better to try GtkTreeRowReference.</p> + +<p>GtkTreeModelFilter and GtkTreeModelSort use persistent iterators (if available) to cache +their GtkTreeRowReference-s. Although ScpTreeStore has a very fast path to iter, and is +generally quite fast, these models may still be slower.</p> + +<h3>top-level "rows-reordered"</h3> + +<b>void user_function(GtkTreeModel *tree_model, GtkTreePath *path, GtkTreeIter *iter, gpointer +new_order, gpointer user_data);</b> + +<p>From the GtkTreeModel documentation (at least gtk+ <= 3.6.4):</p> + +<p>"iter : a valid GtkTreeIter pointing to the node whose" [children have been +reordered?]</p> + +<p>When the top-level rows are being reordered, such iter may not be valid, because it must +point above the top. Both GtkTreeStore and ScpTreeStore pass a pseudo-valid iter which is +suitable for a few operations, but you should not rely on that and check for path depth = +<tt>0</tt> instead.</p> + +<hr> + +<h3><a name="speed">Speed</a></h3> + +<table> +<tr><th>Unsorted store</th><th>Row count</th><th>GtkTreeStore</th> +<th>ScpTreeStore</th><th>Times</th></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level insert with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level iter search double</td><td>25</td><td>0.000</td><td>0.000</td><td>25</td></tr> +<tr><td>top-level iter search string</td><td>25</td><td>0.003</td><td>0.002</td><td>25</td></tr> +<tr><td>top-level linear search double</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr> +<tr><td>top-level linear search string</td><td>25</td><td>n/a</td><td>0.001</td><td>25</td></tr> +<tr><td>top-level quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>25</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 insert_with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>top-level remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>top-level iter search double</td><td>100</td><td>0.006</td><td>0.000</td><td>100</td></tr> +<tr><td>top-level iter search string</td><td>100</td><td>0.034</td><td>0.027</td><td>100</td></tr> +<tr><td>top-level linear search double</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr> +<tr><td>top-level linear search string</td><td>100</td><td>n/a</td><td>0.015</td><td>100</td></tr> +<tr><td>top-level quick sort double</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>100</td><td>0.003</td><td>0.002</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>100</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>100</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>100</td><td>0.005</td><td>0.004</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr> +<tr><td>top-level set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr> +<tr><td>top-level remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr> +<tr><td>top-level insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr> +<tr><td>top-level iter search double</td><td>250</td><td>0.031</td><td>0.003</td><td>250</td></tr> +<tr><td>top-level iter search string</td><td>250</td><td>0.224</td><td>0.183</td><td>250</td></tr> +<tr><td>top-level linear search double</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr> +<tr><td>top-level linear search string</td><td>250</td><td>n/a</td><td>0.109</td><td>250</td></tr> +<tr><td>top-level quick sort double</td><td>250</td><td>0.001</td><td>0.000</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>250</td><td>0.009</td><td>0.008</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>250</td><td>0.001</td><td>0.001</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>250</td><td>0.002</td><td>0.001</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>250</td><td>0.002</td><td>0.000</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>250</td><td>0.015</td><td>0.012</td><td></td></tr> + +<tr><td> </td><td>500</td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr> +<tr><td>top-level set</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr> +<tr><td>top-level remove</td><td>500</td><td>0.002</td><td>0.001</td><td></td></tr> +<tr><td>top-level insert with values</td><td>500</td><td>0.003</td><td>0.002</td><td></td></tr> +<tr><td>top-level iter search double</td><td>500</td><td>0.131</td><td>0.010</td><td>500</td></tr> +<tr><td>top-level iter search string</td><td>500</td><td>0.909</td><td>0.722</td><td>500</td></tr> +<tr><td>top-level linear search double</td><td>500</td><td>n/a</td><td>0.005</td><td>500</td></tr> +<tr><td>top-level linear search string</td><td>500</td><td>n/a</td><td>0.443</td><td>500</td></tr> +<tr><td>top-level quick sort double</td><td>500</td><td>0.003</td><td>0.001</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>500</td><td>0.022</td><td>0.018</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>500</td><td>0.004</td><td>0.002</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>500</td><td>0.002</td><td>0.002</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>500</td><td>0.004</td><td>0.003</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>500</td><td>0.005</td><td>0.001</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>500</td><td>0.034</td><td>0.028</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr> +<tr><td>top-level set</td><td>1000</td><td>0.007</td><td>0.003</td><td></td></tr> +<tr><td>top-level remove</td><td>1000</td><td>0.004</td><td>0.003</td><td></td></tr> +<tr><td>top-level insert with values</td><td>1000</td><td>0.007</td><td>0.004</td><td></td></tr> +<tr><td>top-level iter search double</td><td>1000</td><td>0.052</td><td>0.004</td><td>100</td></tr> +<tr><td>top-level iter search string</td><td>1000</td><td>0.370</td><td>0.273</td><td>100</td></tr> +<tr><td>top-level linear search double</td><td>1000</td><td>n/a</td><td>0.002</td><td>100</td></tr> +<tr><td>top-level linear search string</td><td>1000</td><td>n/a</td><td>0.182</td><td>100</td></tr> +<tr><td>top-level quick sort double</td><td>1000</td><td>0.007</td><td>0.002</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>1000</td><td>0.050</td><td>0.040</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>1000</td><td>0.009</td><td>0.005</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>1000</td><td>0.006</td><td>0.004</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>1000</td><td>0.009</td><td>0.006</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>1000</td><td>0.011</td><td>0.002</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>1000</td><td>0.078</td><td>0.062</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>2500</td><td>0.017</td><td>0.008</td><td></td></tr> +<tr><td>top-level set</td><td>2500</td><td>0.026</td><td>0.009</td><td></td></tr> +<tr><td>top-level remove</td><td>2500</td><td>0.019</td><td>0.008</td><td></td></tr> +<tr><td>top-level insert with values</td><td>2500</td><td>0.026</td><td>0.012</td><td></td></tr> +<tr><td>top-level iter search double</td><td>2500</td><td>0.340</td><td>0.028</td><td>250</td></tr> +<tr><td>top-level iter search string</td><td>2500</td><td>2.273</td><td>1.859</td><td>250</td></tr> +<tr><td>top-level linear search double</td><td>2500</td><td>n/a</td><td>0.015</td><td>250</td></tr> +<tr><td>top-level linear search string</td><td>2500</td><td>n/a</td><td>1.137</td><td>250</td></tr> +<tr><td>top-level quick sort double</td><td>2500</td><td>0.021</td><td>0.004</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>2500</td><td>0.146</td><td>0.117</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>2500</td><td>0.035</td><td>0.014</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>2500</td><td>0.048</td><td>0.014</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>2500</td><td>0.038</td><td>0.013</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>2500</td><td>0.046</td><td>0.017</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>2500</td><td>0.033</td><td>0.007</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>2500</td><td>0.230</td><td>0.181</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>5000</td><td>0.084</td><td>0.019</td><td></td></tr> +<tr><td>top-level set</td><td>5000</td><td>0.107</td><td>0.017</td><td></td></tr> +<tr><td>top-level remove</td><td>5000</td><td>0.089</td><td>0.018</td><td></td></tr> +<tr><td>top-level insert with values</td><td>5000</td><td>0.103</td><td>0.025</td><td></td></tr> +<tr><td>top-level iter search double</td><td>5000</td><td>1.271</td><td>0.112</td><td>500</td></tr> +<tr><td>top-level iter search string</td><td>5000</td><td>8.775</td><td>7.787</td><td>500</td></tr> +<tr><td>top-level linear search double</td><td>5000</td><td>n/a</td><td>0.060</td><td>500</td></tr> +<tr><td>top-level linear search string</td><td>5000</td><td>n/a</td><td>4.351</td><td>500</td></tr> +<tr><td>top-level quick sort double</td><td>5000</td><td>0.046</td><td>0.010</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>5000</td><td>0.325</td><td>0.264</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>5000</td><td>0.168</td><td>0.040</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>5000</td><td>0.201</td><td>0.038</td><td></td></tr> +<tr><td>sublevel 1 remove</td><td>5000</td><td>0.184</td><td>0.038</td><td></td></tr> +<tr><td>sublevel 1 insert with values</td><td>5000</td><td>0.199</td><td>0.046</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>5000</td><td>0.073</td><td>0.015</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>5000</td><td>0.508</td><td>0.405</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>top-level insert</td><td>10000</td><td>0.410</td><td>0.049</td><td></td></tr> +<tr><td>top-level set</td><td>10000</td><td>0.465</td><td>0.035</td><td></td></tr> +<tr><td>top-level remove</td><td>10000</td><td>0.430</td><td>0.045</td><td></td></tr> +<tr><td>top-level insert with values</td><td>10000</td><td>0.461</td><td>0.059</td><td></td></tr> +<tr><td>top-level iter search double</td><td>10000</td><td>7.434</td><td>0.509</td><td>1000</td></tr> +<tr><td>top-level iter search string</td><td>10000</td><td>37.555</td><td>31.020</td><td>1000</td></tr> +<tr><td>top-level linear search double</td><td>10000</td><td>n/a</td><td>0.304</td><td>1000</td></tr> +<tr><td>top-level linear search string</td><td>10000</td><td>n/a</td><td>18.896</td><td>1000</td></tr> +<tr><td>top-level quick sort double</td><td>10000</td><td>0.112</td><td>0.022</td><td></td></tr> +<tr><td>top-level quick sort string</td><td>10000</td><td>0.720</td><td>0.580</td><td></td></tr> +<tr><td>sublevel 1 insert</td><td>10000</td><td>1.152</td><td>0.132</td><td></td></tr> +<tr><td>sublevel 1 set</td><td>10000</td><td>1.730</td><td></td><td>0.116</td></tr> +<tr><td>sublevel 1 remove</td><td>10000</td><td>1.364</td><td>0.128</td><td>0.128</td></tr> +<tr><td>sublevel 1 insert with values</td><td>10000</td><td>1.427</td><td>0.146</td><td></td></tr> +<tr><td>sublevel 1 quick sort double</td><td>10000</td><td>0.170</td><td>0.034</td><td></td></tr> +<tr><td>sublevel 1 quick sort string</td><td>10000</td><td>1.114</td><td>0.893</td><td></td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><th>Store sorted by double</th><th>Row count</th><th>GtkTreeStore</th> +<th>ScpTreeStore</th><th>Times</th></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.000</td><td></td></tr> +<tr><td>pre/append with values</td><td>25</td><td>0.000</td><td>0.000</td><td></td></tr> +<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>100</td><td>0.004</td><td>0.001</td><td></td></tr> +<tr><td>pre/append with values</td><td>100</td><td>0.003</td><td>0.000</td><td></td></tr> +<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.000</td><td>100</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>250</td><td>0.019</td><td>0.003</td><td></td></tr> +<tr><td>pre/append with values</td><td>250</td><td>0.015</td><td>0.001</td><td></td></tr> +<tr><td>binary search</td><td>250</td><td>n/a</td><td>0.001</td><td>250</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>500</td><td>0.068</td><td>0.007</td><td></td></tr> +<tr><td>pre/append with values</td><td>500</td><td>0.054</td><td>0.003</td><td></td></tr> +<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.006</td><td>500</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>1000</td><td>0.225</td><td>0.015</td><td></td></tr> +<tr><td>pre/append with values</td><td>1000</td><td>0.203</td><td>0.006</td><td></td></tr> +<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.023</td><td>1000</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>2500</td><td>1.474</td><td>0.044</td><td></td></tr> +<tr><td>pre/append with values</td><td>2500</td><td>1.324</td><td>0.015</td><td></td></tr> +<tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.147</td><td>2500</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>5000</td><td>6.432</td><td>0.115</td><td></td></tr> +<tr><td>pre/append with values</td><td>5000</td><td>5.624</td><td>0.035</td><td></td></tr> +<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.595</td><td>5000</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>10000</td><td>26.967</td><td>0.335</td><td></td></tr> +<tr><td>pre/append with values</td><td>10000</td><td>23.803</td><td>0.081</td><td></td></tr> +<tr><td>binary search</td><td>10000</td><td>n/a</td><td>3.704</td><td>10000</td></tr> + +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><th>Store sorted by string</th><th>Row count</th><th>GtkTreeStore</th> +<th>ScpTreeStore</th><th>Times</th></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>25</td><td>0.003</td><td>0.001</td><td></td></tr> +<tr><td>pre/append with values</td><td>25</td><td>0.001</td><td>0.001</td><td></td></tr> +<tr><td>binary search</td><td>25</td><td>n/a</td><td>0.000</td><td>25</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>100</td><td>0.014</td><td>0.005</td><td></td></tr> +<tr><td>pre/append with values</td><td>100</td><td>0.014</td><td>0.003</td><td></td></tr> +<tr><td>binary search</td><td>100</td><td>n/a</td><td>0.002</td><td>100</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>250</td><td>0.092</td><td>0.015</td><td></td></tr> +<tr><td>pre/append with values</td><td>250</td><td>0.093</td><td>0.009</td><td></td></tr> +<tr><td>binary search</td><td>250</td><td>n/a</td><td>0.006</td><td>250</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>500</td><td>0.366</td><td>0.034</td><td></td></tr> +<tr><td>pre/append with values</td><td>500</td><td>0.343</td><td>0.021</td><td></td></tr> +<tr><td>binary search</td><td>500</td><td>n/a</td><td>0.012</td><td>500</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>1000</td><td>1.415</td><td>0.077</td><td></td></tr> +<tr><td>pre/append with values</td><td>1000</td><td>1.444</td><td>0.047</td><td></td></tr> +<tr><td>binary search</td><td>1000</td><td>n/a</td><td>0.028</td><td>1000</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>2500</td><td>9.032</td><td>0.229</td><td></td></tr> +<tr><td>pre/append with values</td><td>2500</td><td>9.061</td><td>0.134</td><td></td></tr> +<tr><td>binary search</td><td>2500</td><td>n/a</td><td>0.080</td><td>2500</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>5000</td><td>36.648</td><td>0.521</td><td></td></tr> +<tr><td>pre/append with values</td><td>5000</td><td>38.045</td><td>0.296</td><td></td></tr> +<tr><td>binary search</td><td>5000</td><td>n/a</td><td>0.177</td><td>5000</td></tr> +<tr><td> </td><td></td><td></td><td></td><td></td></tr> +<tr><td>pre/apppend + set</td><td>10000</td><td>slow</td><td>1.225</td><td></td></tr> +<tr><td>pre/append with values</td><td>10000</td><td>slow</td><td>0.654</td><td></td></tr> +<tr><td>binary search</td><td>10000</td><td>n/a</td><td>0.385</td><td>10000</td></tr> + +</table> + +<p>pre/append = prepend for GtkTreeStore (faster than append) and append for ScpTreeStore +(faster than prepend)<br> +all defensive checks enabled, all string tests with utf8 collation</p> + +<p>The difference is easy to explain. First, GtkTreeStore often converts values between their +internal store presentation and GValue, duplicating strings and referencing objects. Second, +binary vs. linear search. Third, invoking the GtkTreeModel implementation functions directly +makes a difference for a lot of calls. Fourth, GtkTreeStore uses lists to keep the row values +and column sort headers, but the columns are arways referenced by index. By itself, inserting +into and removing from a list should be faster than the same array operations. But the store +operations must emit a signal, containing the row path (index), which negates this advantage. +</p> + +<hr> + +<h3><a name="bugs">Bugs</a></h3> + +<p>Probably. In particular, the linguistically correct string comparision is not well tested. +</p> + +<p>Report bugs to <tt><dimitar.zhekov@gmail.com></tt>.</p> + +<h3><a name="copyright">Copyright</a></h3> + +<p>Parts of DND, most defensive programming checks and most of the buildable implementation +are from GtkTreeStore.</p> + +<p><b>GtkTreeStore, Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford</b></p> + +<p>ScpTreeStore was initially written for the Scope plugin of Geany light IDE, which relies +heavily on stores.</p> + +<p><b>ScpTreeStore 0.82, Copyright (C) 2013 Dimitar Toshkov Zhekov</b></p> + +<p>ScpTreeStore is distributed under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your option) any +later version.</p> + +</body> +</html>
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
plugins-commits@lists.geany.org