Commit 741d2d46 authored by Scott Wheeler's avatar Scott Wheeler

Delay cache integrity checking beyond start up time by moving it to the

event loop.  I'm still not completely happy with this solution as it just
sets a fixed three second delay (using a single shot timer), but it's
better than before.

svn path=/trunk/kdemultimedia/juk/; revision=211170
parent 55c97c4d
......@@ -88,11 +88,11 @@ void Cache::load()
CachedTag *t = new CachedTag(fileName);
s >> *t;
// Check the modification time of the file to make sure that
// the cache is current.
if(!t->current())
delete t;
// Just do a dumb read from the cache. Originally cache concistancy was
// checked here, but this means that JuK was having to stat every file
// in the cache while blocking GUI creation. This has since been moved
// to the event loop and is placed in the event loop in the
// CollectionListItem constructor.
}
f.close();
......
......@@ -22,7 +22,8 @@
// public members
////////////////////////////////////////////////////////////////////////////////
CachedTag::CachedTag(const QString &file) : Tag(file), m_externalTag(0), m_tagTrackNumber(0), m_tagYear(0), m_tagSeconds(0), m_tagExists(false)
CachedTag::CachedTag(const QString &file) : Tag(file),
m_externalTag(0), m_tagTrackNumber(0), m_tagYear(0), m_tagSeconds(0), m_tagExists(false)
{
}
......@@ -170,8 +171,7 @@ int CachedTag::seconds() const
bool CachedTag::current() const
{
return(fileExists() &&
m_modificationTime.isValid() &&
return(m_modificationTime.isValid() &&
lastModified().isValid() &&
m_modificationTime >= Tag::lastModified());
}
......
......@@ -58,7 +58,7 @@ public:
/**
* Checks to see if the cache for this item is up to date.
*/
bool current() const;
virtual bool current() const;
QDataStream &read(QDataStream &s);
private:
......
......@@ -23,6 +23,7 @@
#include <kdebug.h>
#include <qclipboard.h>
#include <qtimer.h>
#include "collectionlist.h"
#include "playlistsplitter.h"
......@@ -170,9 +171,24 @@ void CollectionList::addAlbum(const QString &album)
if(album != previousAlbum && !m_albumList.insert(album))
previousAlbum = album;
}
////////////////////////////////////////////////////////////////////////////////
// CollectionListItem public slots
////////////////////////////////////////////////////////////////////////////////
void CollectionListItem::slotRefresh()
{
slotRefreshImpl();
if(CollectionList::instance()) {
CollectionList::instance()->addArtist(text(ArtistColumn));
CollectionList::instance()->addAlbum(text(AlbumColumn));
}
// This is connected to slotRefreshImpl() for all of the items children.
emit(signalRefreshed());
}
////////////////////////////////////////////////////////////////////////////////
// CollectionListItem public methods
// CollectionListItem protected methods
////////////////////////////////////////////////////////////////////////////////
CollectionListItem::CollectionListItem(const QFileInfo &file, const QString &path) : PlaylistItem(CollectionList::instance())
......@@ -190,6 +206,7 @@ CollectionListItem::CollectionListItem(const QFileInfo &file, const QString &pat
<< "CollectionList::initialize() has been called." << endl;
SplashScreen::increment();
QTimer::singleShot(3 * 1000, this, SLOT(slotCheckCurrent()));
}
CollectionListItem::~CollectionListItem()
......@@ -206,19 +223,15 @@ void CollectionListItem::addChildItem(PlaylistItem *child)
}
////////////////////////////////////////////////////////////////////////////////
// CollectionListItem public slots
// CollectionListItem private slots
////////////////////////////////////////////////////////////////////////////////
void CollectionListItem::slotRefresh()
void CollectionListItem::slotCheckCurrent()
{
slotRefreshImpl();
if(CollectionList::instance()) {
CollectionList::instance()->addArtist(text(ArtistColumn));
CollectionList::instance()->addAlbum(text(AlbumColumn));
}
// This is connected to slotRefreshImpl() for all of the items children.
emit(signalRefreshed());
if(!data()->exists() || !data()->isFile())
CollectionList::instance()->clearItem(this);
else if(!data()->tag()->current())
data()->refresh();
}
#include "collectionlist.moc"
......@@ -97,17 +97,30 @@ class CollectionListItem : public PlaylistItem
friend class CollectionList;
friend class PlaylistItem;
Q_OBJECT
/**
* Needs access to the destuctor, even though the destructor isn't used by QDict.
*/
friend class QDict<CollectionListItem>;
public:
virtual ~CollectionListItem();
Q_OBJECT
public slots:
virtual void slotRefresh();
protected:
CollectionListItem(const QFileInfo &file, const QString &path);
virtual ~CollectionListItem();
void addChildItem(PlaylistItem *child);
private slots:
/**
* This slot, called from a QTimer::singleShot() set in the constructor, allows for
* delayed consistancy checking for the cache at the cost of a few CPU cycles. The
* effect however is that stating files is delayed until after the GUI is shown by
* moving this action into the event loop.
*/
void slotCheckCurrent();
};
#endif
......@@ -152,13 +152,20 @@ void Playlist::refresh()
KApplication::restoreOverrideCursor();
}
void Playlist::clearItem(PlaylistItem *item, bool emitChanged)
{
emit signalAboutToRemove(item);
m_members.remove(item->absFilePath());
item->deleteLater();
if(emitChanged)
emit signalNumberOfItemsChanged(this);
}
void Playlist::clearItems(const PlaylistItemList &items)
{
QPtrListIterator<PlaylistItem> it(items);
while(it.current()) {
emit signalAboutToRemove(it.current());
m_members.remove(it.current()->absFilePath());
delete it.current();
clearItem(it.current(), false);
++it;
}
emit signalNumberOfItemsChanged(this);
......
......@@ -61,6 +61,7 @@ public:
virtual void save();
virtual void saveAs();
virtual void refresh();
virtual void clearItem(PlaylistItem *item, bool emitChanged = true);
virtual void clearItems(const PlaylistItemList &items);
/**
......
......@@ -139,6 +139,7 @@ int PlaylistItem::compare(QListViewItem *item, int column, bool ascending) const
int PlaylistItem::compare(const PlaylistItem *firstItem, const PlaylistItem *secondItem, int column, bool ascending) const
{
// Try some very basic caching for "two in a row" searches. From what I've
// seen this is ~15% of all calls.
......
......@@ -22,6 +22,8 @@
#include <qfileinfo.h>
#include <qobject.h>
#include <qptrlist.h>
#include <qptrstack.h>
#include "tag.h"
#include "cache.h"
......@@ -32,22 +34,36 @@ class CollectionListItem;
typedef QPtrList<PlaylistItem> PlaylistItemList;
/**
* Items for the Playlist and the baseclass for CollectionListItem.
* The constructors and destructor are protected and new items should be
* created via Playlist::createItem(). Items should be removed by
* Playlist::clear(), Playlist::deleteFromDisk(), Playlist::clearItem() or
* Playlist::clearItem().
*/
class PlaylistItem : public QObject, public KListViewItem
{
friend class Playlist;
/**
* Needs access to the destuctor, even though the destructor isn't used by QPtrList.
*/
friend class QPtrList<PlaylistItem>;
/**
* Needs access to the destuctor, even though the destructor isn't used by QPtrStack.
*/
friend class QPtrStack<PlaylistItem>;
Q_OBJECT
public:
enum ColumnType { TrackColumn = 0, ArtistColumn = 1, AlbumColumn = 2, TrackNumberColumn = 3,
GenreColumn = 4, YearColumn = 5, LengthColumn = 6, FileNameColumn = 7 };
// The constructors are in the protected secion. See the note there.
virtual ~PlaylistItem();
void setFile(const QString &file);
Tag *tag() const;
void setFile(const QString &file);
// These are just forwarding methods to PlaylistItem::Data, a QFileInfo
// subclass.
......@@ -82,6 +98,12 @@ protected:
PlaylistItem(CollectionListItem *item, Playlist *parent, QListViewItem *after);
PlaylistItem(Playlist *parent);
/**
* See the class documentation for an explanation of construction and deletion
* of PlaylistItems.
*/
virtual ~PlaylistItem();
class Data;
Data *data() { return m_data; }
void setData(Data *d) { m_data = d; }
......
......@@ -108,5 +108,5 @@ SplashScreen::~SplashScreen()
void SplashScreen::processEvents()
{
m_countLabel->setText(QString::number(count));
kapp->processEvents();
kapp->processEvents();
}
......@@ -72,6 +72,13 @@ public:
virtual QString lengthString() const = 0;
virtual int seconds() const = 0;
/**
* Check to see if the item is up to date. This defaults to true and should
* be reimplemented inf Tag types that are not directly mapped to the file
* system (specifically cached tags).
*/
virtual bool current() const { return true; }
// These functions are inlined because they are used on startup -- the most
// performance critical section of JuK.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment