1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-23 16:24:02 +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:
Jordan Lee 2012-07-12 23:37:04 +00:00
parent 54bf01fe0d
commit 463be887fc
2 changed files with 44 additions and 15 deletions

View file

@ -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( ) FileTreeItem :: ~FileTreeItem( )
{ {
assert( myChildren.isEmpty( ) ); assert( myChildren.isEmpty( ) );
if( myParent ) { const int pos = row();
const int pos = myParent->myChildren.indexOf( this ); if( pos < 0 )
if( pos >= 0 ) assert (0 && "failed to remove");
myParent->myChildren.removeAt( pos ); else {
else myParent->myChildren.removeAt( pos );
assert( 0 && "failed to remove" ); myParent->myChildRowsDirty = true;
} }
} }
@ -58,26 +73,35 @@ void
FileTreeItem :: appendChild( FileTreeItem * child ) FileTreeItem :: appendChild( FileTreeItem * child )
{ {
child->myParent = this; child->myParent = this;
myChildren.append( child ); const size_t n = childCount();
myChildren.append (child);
myChildRows.insert (child->name(), n);
} }
FileTreeItem * FileTreeItem *
FileTreeItem :: child( const QString& filename ) FileTreeItem :: child (const QString& filename )
{ {
foreach( FileTreeItem * c, myChildren ) FileTreeItem * item(0);
if( c->name() == filename )
return c;
return 0; const int row = getMyChildRows().value (filename, -1);
if (row != -1)
{
item = child (row);
assert (filename == item->name());
}
return item;
} }
int int
FileTreeItem :: row( ) const FileTreeItem :: row( ) const
{ {
int i(0); int i(-1);
if( myParent ) if( myParent )
i = myParent->myChildren.indexOf( const_cast<FileTreeItem*>(this) ); {
i = myParent->getMyChildRows().value (name(), -1);
}
return i; return i;
} }

View file

@ -17,6 +17,7 @@
#include <QObject> #include <QObject>
#include <QItemDelegate> #include <QItemDelegate>
#include <QList> #include <QList>
#include <QHash>
#include <QSet> #include <QSet>
#include <QSize> #include <QSize>
#include <QString> #include <QString>
@ -43,7 +44,8 @@ class FileTreeItem: public QObject
FileTreeItem( int fileIndex, const QString& name="" ): FileTreeItem( int fileIndex, const QString& name="" ):
myIndex(fileIndex), myParent(0), myName(name), myIndex(fileIndex), myParent(0), myName(name),
myPriority(0), myIsWanted(0), myPriority(0), myIsWanted(0),
myHaveSize(0), myTotalSize(0) { } myHaveSize(0), myTotalSize(0),
myChildRowsDirty(false) { }
public: public:
void appendChild( FileTreeItem *child ); void appendChild( FileTreeItem *child );
@ -72,11 +74,14 @@ class FileTreeItem: public QObject
int myIndex; int myIndex;
FileTreeItem * myParent; FileTreeItem * myParent;
QList<FileTreeItem*> myChildren; QList<FileTreeItem*> myChildren;
QHash<QString,int> myChildRows;
QHash<QString,int>& getMyChildRows();
const QString myName; const QString myName;
int myPriority; int myPriority;
bool myIsWanted; bool myIsWanted;
uint64_t myHaveSize; uint64_t myHaveSize;
uint64_t myTotalSize; uint64_t myTotalSize;
bool myChildRowsDirty;
}; };
class FileTreeModel: public QAbstractItemModel class FileTreeModel: public QAbstractItemModel