1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 14:16:32 +02:00

Memoize visibility filter

This commit is contained in:
Uwe L. Korn
2014-10-12 11:29:44 +01:00
parent b970cf1433
commit f85e34a3e9
2 changed files with 37 additions and 13 deletions

View File

@@ -145,20 +145,22 @@ PlayableProxyModel::setSourcePlayableModel( PlayableModel* sourceModel )
bool bool
PlayableProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const PlayableProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{ {
PlayableProxyModelFilterMemo memo;
PlayableItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) ); PlayableItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
if ( !pi ) if ( !pi )
return false; return false;
return filterAcceptsRowInternal( sourceRow, pi, sourceParent ); return filterAcceptsRowInternal( sourceRow, pi, sourceParent, memo );
} }
bool bool
PlayableProxyModel::filterAcceptsRowInternal( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const PlayableProxyModel::filterAcceptsRowInternal( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const
{ {
if ( m_maxVisibleItems > 0 && !visibilityFilterAcceptsRow( sourceRow, sourceParent ) ) if ( m_maxVisibleItems > 0 && !visibilityFilterAcceptsRow( sourceRow, sourceParent, memo ) )
return false; return false;
if ( m_hideDupeItems && !dupeFilterAcceptsRow( sourceRow, pi, sourceParent ) ) if ( m_hideDupeItems && !dupeFilterAcceptsRow( sourceRow, pi, sourceParent, memo ) )
return false; return false;
return nameFilterAcceptsRow( sourceRow, pi, sourceParent ); return nameFilterAcceptsRow( sourceRow, pi, sourceParent );
@@ -166,7 +168,7 @@ PlayableProxyModel::filterAcceptsRowInternal( int sourceRow, PlayableItem* pi, c
bool bool
PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const
{ {
if ( !m_hideDupeItems ) if ( !m_hideDupeItems )
return true; return true;
@@ -181,7 +183,7 @@ PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const
( pi->album() && pi->album() == di->album() ) || ( pi->album() && pi->album() == di->album() ) ||
( pi->artist() && pi->artist()->name() == di->artist()->name() ); ( pi->artist() && pi->artist()->name() == di->artist()->name() );
if ( b && filterAcceptsRowInternal( i, di, sourceParent ) ) if ( b && filterAcceptsRowInternal( i, di, sourceParent, memo ) )
return false; return false;
} }
@@ -190,18 +192,26 @@ PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const
bool bool
PlayableProxyModel::visibilityFilterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const PlayableProxyModel::visibilityFilterAcceptsRow( int sourceRow, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const
{ {
if ( m_maxVisibleItems <= 0 ) if ( m_maxVisibleItems <= 0 )
return true; return true;
int items = 0; if ( static_cast<size_t>( sourceRow ) < memo.visibilty.size() )
for ( int i = 0; ( i < sourceRow ) && ( items < m_maxVisibleItems ) ; i++ ) {
// We have already memoized the return value.
return memo.visibilty[sourceRow] < m_maxVisibleItems;
}
int items = memo.visibilty.back();
for ( int i = memo.visibilty.size() - 1; ( i < sourceRow ) && ( items < m_maxVisibleItems ) ; i++ )
{ {
PlayableItem* pi = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) ); PlayableItem* pi = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
if ( pi && dupeFilterAcceptsRow( i, pi, sourceParent ) && nameFilterAcceptsRow( i, pi, sourceParent ) ) // We will not change memo in these calls as all values needed in them are already memoized.
if ( pi && dupeFilterAcceptsRow( i, pi, sourceParent, memo ) && nameFilterAcceptsRow( i, pi, sourceParent ) )
{ {
items++; items++;
memo.visibilty.push_back( items ); // Sets memo.visibilty[i + 1] to items
} }
} }

View File

@@ -27,6 +27,20 @@
#include "DllMacro.h" #include "DllMacro.h"
class PlayableProxyModelFilterMemo
{
public:
PlayableProxyModelFilterMemo()
{
// First element always has no predecessors.
// TODO C++11: Make this a constexpr using initializer lists.
visibilty.push_back( 0 );
}
virtual ~PlayableProxyModelFilterMemo() {}
std::vector<int> visibilty;
};
class DLLEXPORT PlayableProxyModel : public QSortFilterProxyModel class DLLEXPORT PlayableProxyModel : public QSortFilterProxyModel
{ {
Q_OBJECT Q_OBJECT
@@ -117,10 +131,10 @@ private slots:
void onCurrentIndexChanged( const QModelIndex& newIndex, const QModelIndex& oldIndex ); void onCurrentIndexChanged( const QModelIndex& newIndex, const QModelIndex& oldIndex );
private: private:
bool filterAcceptsRowInternal( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const; bool filterAcceptsRowInternal( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const;
bool nameFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const; bool nameFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const;
bool dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent ) const; bool dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const;
bool visibilityFilterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const; bool visibilityFilterAcceptsRow( int sourceRow, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const;
bool lessThan( int column, const Tomahawk::query_ptr& left, const Tomahawk::query_ptr& right ) const; bool lessThan( int column, const Tomahawk::query_ptr& left, const Tomahawk::query_ptr& right ) const;
PlayableModel* m_model; PlayableModel* m_model;