Skip to content

Commit

Permalink
[GTK] Fix slowdown in setItemCount()
Browse files Browse the repository at this point in the history
The slowdown was caused by update of insertion iterator, that was
avoidable when insertion happens at the beginning of GTK model.
  • Loading branch information
basilevs committed Jan 23, 2024
1 parent 90baece commit 8da6e41
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3342,42 +3342,37 @@ void _setItemCount (TreeItem parentItem, long parentIter, List<TreeItem> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 8da6e41

Please sign in to comment.