Optimize wxDataViewMainWindow::FindNode() in generic wxDataViewCtrl.
Avoid unnecessary heap allocations and extra indirections and just use the items pointers directly. Also avoid copying the (potentially huge) nodes arrays. Closes #12647. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66004 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1273,7 +1273,7 @@ void wxDataViewRenameTimer::Notify()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// The tree building helper, declared firstly
|
// The tree building helper, declared firstly
|
||||||
static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item,
|
static void BuildTreeHelper( const wxDataViewModel * model, const wxDataViewItem & item,
|
||||||
wxDataViewTreeNode * node);
|
wxDataViewTreeNode * node);
|
||||||
|
|
||||||
int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
|
int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 )
|
||||||
@@ -2969,28 +2969,26 @@ void wxDataViewMainWindow::Collapse(unsigned int row)
|
|||||||
|
|
||||||
wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item )
|
wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item )
|
||||||
{
|
{
|
||||||
wxDataViewModel * model = GetOwner()->GetModel();
|
const wxDataViewModel * model = GetOwner()->GetModel();
|
||||||
if( model == NULL )
|
if( model == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!item.IsOk())
|
if (!item.IsOk())
|
||||||
return m_root;
|
return m_root;
|
||||||
|
|
||||||
// Compose the a parent-chain of the finding item
|
// Compose the parent-chain for the item we are looking for
|
||||||
ItemList list;
|
wxVector<wxDataViewItem> parentChain;
|
||||||
list.DeleteContents( true );
|
|
||||||
wxDataViewItem it( item );
|
wxDataViewItem it( item );
|
||||||
while( it.IsOk() )
|
while( it.IsOk() )
|
||||||
{
|
{
|
||||||
wxDataViewItem * pItem = new wxDataViewItem( it );
|
parentChain.push_back(it);
|
||||||
list.Insert( pItem );
|
it = model->GetParent(it);
|
||||||
it = model->GetParent( it );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the item along the parent-chain.
|
// Find the item along the parent-chain.
|
||||||
// This algorithm is designed to speed up the node-finding method
|
// This algorithm is designed to speed up the node-finding method
|
||||||
wxDataViewTreeNode * node = m_root;
|
wxDataViewTreeNode* node = m_root;
|
||||||
for( ItemList::const_iterator iter = list.begin(); iter !=list.end(); iter++ )
|
for( unsigned iter = parentChain.size()-1; iter>=0; --iter )
|
||||||
{
|
{
|
||||||
if( node->HasChildren() )
|
if( node->HasChildren() )
|
||||||
{
|
{
|
||||||
@@ -3000,18 +2998,18 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item
|
|||||||
::BuildTreeHelper(model, node->GetItem(), node);
|
::BuildTreeHelper(model, node->GetItem(), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDataViewTreeNodes nodes = node->GetNodes();
|
const wxDataViewTreeNodes& nodes = node->GetNodes();
|
||||||
unsigned int i;
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (i = 0; i < nodes.GetCount(); i ++)
|
for (unsigned i = 0; i < nodes.GetCount(); ++i)
|
||||||
{
|
{
|
||||||
if (nodes[i]->GetItem() == (**iter))
|
wxDataViewTreeNode* currentNode = nodes[i];
|
||||||
|
if (currentNode->GetItem() == parentChain[iter])
|
||||||
{
|
{
|
||||||
if (nodes[i]->GetItem() == item)
|
if (currentNode->GetItem() == item)
|
||||||
return nodes[i];
|
return currentNode;
|
||||||
|
|
||||||
node = nodes[i];
|
node = currentNode;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3131,7 +3129,7 @@ int wxDataViewMainWindow::RecalculateCount()
|
|||||||
class ItemToRowJob : public DoJob
|
class ItemToRowJob : public DoJob
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ItemToRowJob(const wxDataViewItem& item_, ItemList::const_iterator iter)
|
ItemToRowJob(const wxDataViewItem& item_, wxVector<wxDataViewItem>::reverse_iterator iter)
|
||||||
: m_iter(iter),
|
: m_iter(iter),
|
||||||
item(item_)
|
item(item_)
|
||||||
{
|
{
|
||||||
@@ -3147,7 +3145,7 @@ public:
|
|||||||
return DoJob::OK;
|
return DoJob::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( node->GetItem() == **m_iter )
|
if( node->GetItem() == *m_iter )
|
||||||
{
|
{
|
||||||
m_iter++;
|
m_iter++;
|
||||||
return DoJob::CONT;
|
return DoJob::CONT;
|
||||||
@@ -3173,7 +3171,7 @@ public:
|
|||||||
{ return ret -1; }
|
{ return ret -1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ItemList::const_iterator m_iter;
|
wxVector<wxDataViewItem>::reverse_iterator m_iter;
|
||||||
wxDataViewItem item;
|
wxDataViewItem item;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -3194,27 +3192,27 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const
|
|||||||
if( !item.IsOk() )
|
if( !item.IsOk() )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Compose the a parent-chain of the finding item
|
// Compose the parent-chain of the item we are looking for
|
||||||
ItemList list;
|
wxVector<wxDataViewItem> parentChain;
|
||||||
wxDataViewItem * pItem;
|
|
||||||
list.DeleteContents( true );
|
|
||||||
wxDataViewItem it( item );
|
wxDataViewItem it( item );
|
||||||
while( it.IsOk() )
|
while( it.IsOk() )
|
||||||
{
|
{
|
||||||
pItem = new wxDataViewItem( it );
|
parentChain.push_back(it);
|
||||||
list.Insert( pItem );
|
it = model->GetParent(it);
|
||||||
it = model->GetParent( it );
|
|
||||||
}
|
}
|
||||||
pItem = new wxDataViewItem( );
|
|
||||||
list.Insert( pItem );
|
|
||||||
|
|
||||||
ItemToRowJob job( item, list.begin() );
|
// add an 'invalid' item to represent our 'invisible' root node
|
||||||
Walker(m_root , job );
|
parentChain.push_back(wxDataViewItem());
|
||||||
|
|
||||||
|
// the parent chain was created by adding the deepest parent first.
|
||||||
|
// so if we want to start at the root node, we have to iterate backwards through the vector
|
||||||
|
ItemToRowJob job( item, parentChain.rbegin() );
|
||||||
|
Walker( m_root, job );
|
||||||
return job.GetResult();
|
return job.GetResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item,
|
static void BuildTreeHelper( const wxDataViewModel * model, const wxDataViewItem & item,
|
||||||
wxDataViewTreeNode * node)
|
wxDataViewTreeNode * node)
|
||||||
{
|
{
|
||||||
if( !model->IsContainer( item ) )
|
if( !model->IsContainer( item ) )
|
||||||
|
Reference in New Issue
Block a user