Merge branch 'gtk-dvc-faster-insert'

Improve performance of wxGTK wxDataViewCtrl when inserting many items.

See https://github.com/wxWidgets/wxWidgets/pull/2313
This commit is contained in:
Vadim Zeitlin
2021-04-07 12:39:29 +02:00

View File

@@ -244,6 +244,13 @@ public:
bool IsSorted() const { return m_sort_column >= 0; }
// Freezing sort temporarily disables sorting when inserting the items into
// the tree as an optimization when inserting many items. Sort must be
// thawed, by calling FreezeSort(false), before inserting the last item to
// ensure that the items still end up in the right order.
void FreezeSort(bool freeze) { m_sort_frozen = freeze; }
bool IsSortFrozen() const { return m_sort_frozen; }
// Should we be sorted either because we have a configured sort column or
// because we have a default sort order?
bool ShouldBeSorted() const
@@ -286,6 +293,7 @@ private:
GtkSortType m_sort_order;
wxDataViewColumn *m_dataview_sort_column;
int m_sort_column;
bool m_sort_frozen;
GtkTargetEntry m_dragSourceTargetEntry;
wxCharBuffer m_dragSourceTargetEntryTarget;
@@ -352,7 +360,7 @@ public:
m_children.Add( id );
if (m_internal->ShouldBeSorted())
if ( !m_internal->IsSortFrozen() && m_internal->ShouldBeSorted() )
{
gs_internal = m_internal;
m_children.Sort( &wxGtkTreeModelChildCmp );
@@ -399,7 +407,7 @@ public:
{
m_children.Insert( id, pos );
if (m_internal->ShouldBeSorted())
if ( !m_internal->IsSortFrozen() && m_internal->ShouldBeSorted() )
{
gs_internal = m_internal;
m_children.Sort( &wxGtkTreeModelChildCmp );
@@ -451,6 +459,8 @@ public:
wxDataViewItem &GetItem() { return m_item; }
wxDataViewCtrlInternal *GetInternal() { return m_internal; }
void FreezeSort(bool freeze) { m_internal->FreezeSort(freeze); }
void Resort();
private:
@@ -3624,6 +3634,7 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataVie
m_root = NULL;
m_sort_order = GTK_SORT_ASCENDING;
m_sort_column = -1;
m_sort_frozen = false;
m_dataview_sort_column = NULL;
m_dragDataObject = NULL;
@@ -3719,11 +3730,21 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
wxDataViewItemArray children;
unsigned int count = m_wx_model->GetChildren( node->GetItem(), children );
// Avoid sorting children multiple times when inserting many nodes,
// this results in O(N^2*log(N)) complexity.
if ( count > 1 )
node->FreezeSort(true);
unsigned int pos;
for (pos = 0; pos < count; pos++)
{
wxDataViewItem child = children[pos];
// Rr-enable sorting before inserting the last child if we had
// disabled it above.
if ( pos == count - 1 && pos != 0 )
node->FreezeSort(false);
if (m_wx_model->IsContainer( child ))
node->AddNode( new wxGtkTreeModelNode( node, child, this ) );
else