From 8da6e4144cabdb9bab71d8f8b4ff736f7e9e28bf Mon Sep 17 00:00:00 2001 From: Vasili Gulevich Date: Tue, 23 Jan 2024 21:34:22 +0000 Subject: [PATCH] [GTK] Fix slowdown in setItemCount() The slowdown was caused by update of insertion iterator, that was avoidable when insertion happens at the beginning of GTK model. --- .../gtk/org/eclipse/swt/widgets/Tree.java | 49 +++++++++---------- .../gtk/org/eclipse/swt/widgets/TreeItem.java | 8 ++- 2 files changed, 29 insertions(+), 28 deletions(-) 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 ea8f69239e..99079e99e3 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 @@ -3342,42 +3342,37 @@ void _setItemCount (TreeItem parentItem, long parentIter, List items, if (currentSize - 1 != items.size () ) throw new AssertionError ("Items should cleanup sibling list on disposal"); } - long modificationIter = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); - if (modificationIter == 0) error (SWT.ERROR_NO_HANDLES); - try { - int oldSize = items.size (); - assert GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter) == oldSize; - if (items.size () > count) { - GTK.gtk_tree_model_iter_nth_child (modelHandle, modificationIter, parentIter, count); + int oldSize = items.size (); + assert GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter) == oldSize; + if (items.size () > count) { + long removeIter = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); + if (removeIter == 0) error (SWT.ERROR_NO_HANDLES); + try { + GTK.gtk_tree_model_iter_nth_child (modelHandle, removeIter, parentIter, count); items.subList (count, items.size ()).clear (); long selection = GTK.gtk_tree_view_get_selection (parent.handle); for (int i = count; i < oldSize; i++) { OS.g_signal_handlers_block_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); - GTK.gtk_tree_store_remove (modelHandle, modificationIter); + GTK.gtk_tree_store_remove (modelHandle, removeIter); OS.g_signal_handlers_unblock_matched (selection, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED); } - } else if (items.size () < count) { - if (items.size () > 0) { - GTK.gtk_tree_model_iter_nth_child (modelHandle, modificationIter, parentIter, oldSize - 1); - } - items.addAll(Collections.nCopies (count - items.size(), null)); - long createdIter = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); - if (createdIter == 0) error (SWT.ERROR_NO_HANDLES); - try { - for (int i = oldSize; i < count; i++) { - GTK.gtk_tree_store_insert_after (modelHandle, createdIter, parentIter, i == 0 ? 0 : modificationIter); - TreeItem result = new TreeItem (this, parentItem, SWT.NONE, i, createdIter); - assert items.get(i) == result : "TreeItem should self-insert into sibling list"; - C.memmove (modificationIter, createdIter, GTK.GtkTreeIter_sizeof ()); - } - } finally { - OS.g_free (createdIter); + } finally { + OS.g_free (removeIter); + } + } else if (items.size () < count) { + long createdIter = OS.g_malloc (GTK.GtkTreeIter_sizeof ()); + if (createdIter == 0) error (SWT.ERROR_NO_HANDLES); + try { + for (int i = oldSize; i < count; i++) { + TreeItem result = new TreeItem (this, parentItem, SWT.NONE, oldSize, 0); + assert items.get(oldSize) == result : "TreeItem should self-insert into sibling list"; } + } finally { + OS.g_free (createdIter); } - assert GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter) == count; - } finally { - OS.g_free (modificationIter); } + assert GTK.gtk_tree_model_iter_n_children (modelHandle, parentIter) == count; + assert items.size() == count; } finally { setRedraw(true); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java index e5dd0015e4..2b37ef9284 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java @@ -203,6 +203,10 @@ public TreeItem (TreeItem parentItem, int style, int index) { */ GTK.gtk_tree_store_append (parent.modelHandle, handle, parentIter); siblings.add (this); + } else if (siblings.get(index - 1) != null) { + TreeItem insertAfterItem = siblings.get(index - 1); + GTK.gtk_tree_store_insert_after (parent.modelHandle, handle, parentIter, insertAfterItem.handle); + siblings.add (index, this); } else { GTK.gtk_tree_store_insert (parent.modelHandle, handle, parentIter, index); siblings.add (index, this); @@ -859,7 +863,9 @@ public TreeItem getItem (int index) { if (index < 0) error (SWT.ERROR_INVALID_RANGE); if (index >= items.size()) error (SWT.ERROR_INVALID_RANGE); if (!parent.checkData (this)) error (SWT.ERROR_WIDGET_DISPOSED); - return parent._getItem(this, items, index); + TreeItem result = parent._getItem(this, items, index); + assert result.treeStoreIndexOf() == index; + return result; } TreeItem _peekItem (int index) {