diff options
author | Alexandr Miloslavskiy | 2019-07-04 16:42:39 +0000 |
---|---|---|
committer | Eric Williams | 2019-07-08 15:05:22 +0000 |
commit | de95eb78d372a16b034c585d679aa7cfffc17c4d (patch) | |
tree | 5648dfceb53c76412db0f44ff5af611a0ec2c53b /bundles | |
parent | 55db773f4bc800bba4f3ba9aaf18947fbe362e6d (diff) | |
download | eclipse.platform.swt-de95eb78d372a16b034c585d679aa7cfffc17c4d.tar.gz eclipse.platform.swt-de95eb78d372a16b034c585d679aa7cfffc17c4d.tar.xz eclipse.platform.swt-de95eb78d372a16b034c585d679aa7cfffc17c4d.zip |
Bug 548982 - [GTK] Optimize bulk inserting items to Tree
Change-Id: I1b6c19d043cc42ac244926129eef2ba71ef174ad
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
Diffstat (limited to 'bundles')
5 files changed, 57 insertions, 10 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index dfab9f7cd9..e0326b8506 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -11008,6 +11008,16 @@ fail: } #endif +#ifndef NO__1gtk_1tree_1store_1prepend +JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1tree_1store_1prepend) + (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2) +{ + GTK_NATIVE_ENTER(env, that, _1gtk_1tree_1store_1prepend_FUNC); + gtk_tree_store_prepend((GtkTreeStore *)arg0, (GtkTreeIter *)arg1, (GtkTreeIter *)arg2); + GTK_NATIVE_EXIT(env, that, _1gtk_1tree_1store_1prepend_FUNC); +} +#endif + #ifndef NO__1gtk_1tree_1store_1remove JNIEXPORT void JNICALL GTK_NATIVE(_1gtk_1tree_1store_1remove) (JNIEnv *env, jclass that, jlong arg0, jlong arg1) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 8589c73125..3512668735 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -875,6 +875,7 @@ char * GTK_nativeFunctionNames[] = { "_1gtk_1tree_1store_1clear", "_1gtk_1tree_1store_1insert", "_1gtk_1tree_1store_1newv", + "_1gtk_1tree_1store_1prepend", "_1gtk_1tree_1store_1remove", "_1gtk_1tree_1store_1set__JJIII", "_1gtk_1tree_1store_1set__JJIJI", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index 73994032b7..642bc88848 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -873,6 +873,7 @@ typedef enum { _1gtk_1tree_1store_1clear_FUNC, _1gtk_1tree_1store_1insert_FUNC, _1gtk_1tree_1store_1newv_FUNC, + _1gtk_1tree_1store_1prepend_FUNC, _1gtk_1tree_1store_1remove_FUNC, _1gtk_1tree_1store_1set__JJIII_FUNC, _1gtk_1tree_1store_1set__JJIJI_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java index eae8f49f1e..5b811b8691 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GTK.java @@ -7565,6 +7565,20 @@ public class GTK extends OS { /** * @param store cast=(GtkTreeStore *) * @param iter cast=(GtkTreeIter *) + * @param parent cast=(GtkTreeIter *) + */ + public static final native void _gtk_tree_store_prepend(long store, long iter, long parent); + public static final void gtk_tree_store_prepend(long store, long iter, long parent) { + lock.lock(); + try { + _gtk_tree_store_prepend(store, iter, parent); + } finally { + lock.unlock(); + } + } + /** + * @param store cast=(GtkTreeStore *) + * @param iter cast=(GtkTreeIter *) */ public static final native void _gtk_tree_store_remove(long store, long iter); public static final void gtk_tree_store_remove(long store, long iter) { diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java index 0ef25d72fa..77975e12c4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java @@ -890,21 +890,42 @@ void createItem (TreeColumn column, int index) { } } +/* + * NOTE: the fastest way to bulk-insert items is to insert every item + * at index 0 (insert in reverse to preserve order). + */ void createItem (TreeItem item, long parentIter, int index) { - int count = GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter); - if (index == -1) index = count; - if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE); - item.handle = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); - if (item.handle == 0) error(SWT.ERROR_NO_HANDLES); /* - * Feature in GTK. It is much faster to append to a tree store - * than to insert at the end using gtk_tree_store_insert(). - */ - if (index == count) { + * Try to achieve maximum possible performance in bulk insert scenarios. + * Even a single call to 'gtk_tree_model_iter_n_children' already + * reduces performance 3x, so try to avoid any unneeded API calls. + */ + if (index == 0) { + item.handle = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); + if (item.handle == 0) error(SWT.ERROR_NO_HANDLES); + GTK.gtk_tree_store_prepend (modelHandle, item.handle, parentIter); + } else if (index == -1) { + item.handle = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); + if (item.handle == 0) error(SWT.ERROR_NO_HANDLES); GTK.gtk_tree_store_append (modelHandle, item.handle, parentIter); } else { - GTK.gtk_tree_store_insert (modelHandle, item.handle, parentIter, index); + int count = GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter); + if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE); + + item.handle = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); + if (item.handle == 0) error(SWT.ERROR_NO_HANDLES); + + /* + * Feature in GTK. It is much faster to append to a tree store + * than to insert at the end using gtk_tree_store_insert(). + */ + if (index == count) { + GTK.gtk_tree_store_append (modelHandle, item.handle, parentIter); + } else { + GTK.gtk_tree_store_insert (modelHandle, item.handle, parentIter, index); + } } + int id = getId (item.handle, false); items [id] = item; modelChanged = true; |