mirror of
https://github.com/transmission/transmission
synced 2024-12-23 08:13:27 +00:00
(trunk, qt) #4961 -- make the file list more responsive when a torrent has an extreme number of files.
Before this patch, the test torrent I had with ~10k files took 8 seconds to load. After this patch, it takes less than 1 second.
This commit is contained in:
parent
54bf01fe0d
commit
463be887fc
2 changed files with 44 additions and 15 deletions
|
@ -41,16 +41,31 @@ enum
|
|||
*****
|
||||
****/
|
||||
|
||||
QHash<QString,int>&
|
||||
FileTreeItem :: getMyChildRows()
|
||||
{
|
||||
// if necessary, revalidate the name-to-row mapping
|
||||
if( myChildRowsDirty ) {
|
||||
myChildRows.clear();
|
||||
for (size_t i=0, n=childCount(); i<n; ++i)
|
||||
myChildRows.insert (child(i)->name(), i);
|
||||
myChildRowsDirty = false;
|
||||
}
|
||||
|
||||
return myChildRows;
|
||||
}
|
||||
|
||||
|
||||
FileTreeItem :: ~FileTreeItem( )
|
||||
{
|
||||
assert( myChildren.isEmpty( ) );
|
||||
|
||||
if( myParent ) {
|
||||
const int pos = myParent->myChildren.indexOf( this );
|
||||
if( pos >= 0 )
|
||||
myParent->myChildren.removeAt( pos );
|
||||
else
|
||||
assert( 0 && "failed to remove" );
|
||||
const int pos = row();
|
||||
if( pos < 0 )
|
||||
assert (0 && "failed to remove");
|
||||
else {
|
||||
myParent->myChildren.removeAt( pos );
|
||||
myParent->myChildRowsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,26 +73,35 @@ void
|
|||
FileTreeItem :: appendChild( FileTreeItem * child )
|
||||
{
|
||||
child->myParent = this;
|
||||
myChildren.append( child );
|
||||
const size_t n = childCount();
|
||||
myChildren.append (child);
|
||||
myChildRows.insert (child->name(), n);
|
||||
}
|
||||
|
||||
FileTreeItem *
|
||||
FileTreeItem :: child( const QString& filename )
|
||||
FileTreeItem :: child (const QString& filename )
|
||||
{
|
||||
foreach( FileTreeItem * c, myChildren )
|
||||
if( c->name() == filename )
|
||||
return c;
|
||||
FileTreeItem * item(0);
|
||||
|
||||
return 0;
|
||||
const int row = getMyChildRows().value (filename, -1);
|
||||
if (row != -1)
|
||||
{
|
||||
item = child (row);
|
||||
assert (filename == item->name());
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
int
|
||||
FileTreeItem :: row( ) const
|
||||
{
|
||||
int i(0);
|
||||
int i(-1);
|
||||
|
||||
if( myParent )
|
||||
i = myParent->myChildren.indexOf( const_cast<FileTreeItem*>(this) );
|
||||
{
|
||||
i = myParent->getMyChildRows().value (name(), -1);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QObject>
|
||||
#include <QItemDelegate>
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
|
@ -43,7 +44,8 @@ class FileTreeItem: public QObject
|
|||
FileTreeItem( int fileIndex, const QString& name="" ):
|
||||
myIndex(fileIndex), myParent(0), myName(name),
|
||||
myPriority(0), myIsWanted(0),
|
||||
myHaveSize(0), myTotalSize(0) { }
|
||||
myHaveSize(0), myTotalSize(0),
|
||||
myChildRowsDirty(false) { }
|
||||
|
||||
public:
|
||||
void appendChild( FileTreeItem *child );
|
||||
|
@ -72,11 +74,14 @@ class FileTreeItem: public QObject
|
|||
int myIndex;
|
||||
FileTreeItem * myParent;
|
||||
QList<FileTreeItem*> myChildren;
|
||||
QHash<QString,int> myChildRows;
|
||||
QHash<QString,int>& getMyChildRows();
|
||||
const QString myName;
|
||||
int myPriority;
|
||||
bool myIsWanted;
|
||||
uint64_t myHaveSize;
|
||||
uint64_t myTotalSize;
|
||||
bool myChildRowsDirty;
|
||||
};
|
||||
|
||||
class FileTreeModel: public QAbstractItemModel
|
||||
|
|
Loading…
Reference in a new issue