speed up browsing media library

the way media library was searching for albums
was wrong and by the way totally inefficient.
This commit is contained in:
Andrzej Rybczak
2009-03-07 12:26:16 +01:00
parent 93fd687ec1
commit a4599fffe7
8 changed files with 45 additions and 58 deletions

View File

@@ -73,8 +73,6 @@
#
#song_library_format = "{%n - }{%t}|{%f}"
#
#media_library_album_format = "{(%y) }%b"
#
#tag_editor_album_format = "{(%y) }%b"
#
#browser_playlist_prefix = "$2playlist$9 "

View File

@@ -19,7 +19,6 @@
***************************************************************************/
#include <algorithm>
#include <map>
#include "charset.h"
#include "display.h"
@@ -151,52 +150,46 @@ void MediaLibrary::Update()
{
Albums->Reset();
TagList list;
std::map<std::string, SearchConstraints, CaseInsensitiveSorting> maplist;
locale_to_utf(Artists->Current());
if (Config.media_lib_primary_tag == MPD_TAG_ITEM_ARTIST)
Mpd->GetAlbums(Artists->Current(), list);
else
{
Mpd->StartSearch(1);
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
Mpd->StartFieldSearch(MPD_TAG_ITEM_ALBUM);
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
Mpd->CommitSearch(list);
}
// <mpd-0.14 doesn't support searching for empty tag
if (Mpd->Version() > 13)
{
SongList noalbum_list;
Mpd->StartSearch(1);
TagList noalbum_list;
Mpd->StartFieldSearch(MPD_TAG_ITEM_FILENAME);
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, "");
Mpd->CommitSearch(noalbum_list);
if (!noalbum_list.empty())
Albums->AddOption(std::make_pair("<no album>", SearchConstraints("", "")));
FreeSongList(noalbum_list);
}
for (TagList::iterator it = list.begin(); it != list.end(); it++)
{
if (it->empty())
continue;
SongList l;
Mpd->StartSearch(1);
TagList l;
Mpd->StartFieldSearch(MPD_TAG_ITEM_DATE);
Mpd->AddSearch(Config.media_lib_primary_tag, Artists->Current());
Mpd->AddSearch(MPD_TAG_ITEM_ALBUM, *it);
Mpd->CommitSearch(l);
sort(l.begin(), l.end(), SortSongsByYear);
for (SongList::const_iterator j = l.begin(); j != l.end(); j++)
utf_to_locale(*it);
if (l.empty())
{
utf_to_locale(*it);
(*j)->Localize();
maplist[(*j)->toString(Config.media_lib_album_format)] = SearchConstraints(*it, (*j)->GetYear());
Albums->AddOption(std::make_pair(*it, SearchConstraints(*it, "")));
continue;
}
FreeSongList(l);
for (TagList::const_iterator j = l.begin(); j != l.end(); j++)
Albums->AddOption(std::make_pair("(" + *j + ") " + *it, SearchConstraints(*it, *j)));
}
utf_to_locale(Artists->Current());
for (std::map<std::string, SearchConstraints>::const_iterator it = maplist.begin(); it != maplist.end(); it++)
Albums->AddOption(make_pair(it->first, it->second));
Albums->Sort<CaseInsensitiveSorting>((*Albums)[0].first == "<no album>");
Albums->Window::Clear();
Albums->Refresh();
}

View File

@@ -28,7 +28,6 @@ class MediaLibrary : public Screen<Window>
{
struct SearchConstraints
{
SearchConstraints() { }
SearchConstraints(const std::string &album, const std::string &year) : Album(album), Year(year) { }
std::string Album;

View File

@@ -76,6 +76,11 @@ namespace NCurses
bool isStatic;
};
template <class ComparisonClass> static bool InternalSorting(Option *a, Option *b)
{
return ComparisonClass()(a->Item, b->Item);
}
typedef typename std::vector<Option *>::iterator option_iterator;
typedef typename std::vector<Option *>::const_iterator option_const_iterator;
@@ -128,6 +133,14 @@ namespace NCurses
virtual void Reset();
virtual void Clear(bool clrscr = 1);
template <class Compare> void Sort(size_t beginning = 0)
{
if (itsOptions.empty())
return;
sort(itsOptions.begin()+beginning, itsOptions.end(), InternalSorting<Compare>);
ClearFiltered();
}
void SetSelectPrefix(Buffer *b) { itsSelectedPrefix = b; }
void SetSelectSuffix(Buffer *b) { itsSelectedSuffix = b; }
@@ -149,6 +162,8 @@ namespace NCurses
virtual Menu<T> *EmptyClone() const;
protected:
void ClearFiltered();
ItemDisplayer itsItemDisplayer;
void *itsItemDisplayerUserdata;
GetStringFunction itsGetStringFunction;
@@ -462,14 +477,20 @@ template <class T> void NCurses::Menu<T>::Reset()
itsBeginning = 0;
}
template <class T> void NCurses::Menu<T>::ClearFiltered()
{
itsFilteredOptions.clear();
itsFilteredRealPositions.clear();
itsFilter.clear();
itsOptionsPtr = &itsOptions;
}
template <class T> void NCurses::Menu<T>::Clear(bool clrscr)
{
for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
delete *it;
itsOptions.clear();
itsFilteredOptions.clear();
itsFilteredRealPositions.clear();
itsFilter.clear();
ClearFiltered();
itsOptionsPtr = &itsOptions;
if (clrscr)
Window::Clear();
@@ -557,12 +578,10 @@ template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter,
{
if (filter == itsFilter)
return;
ClearFiltered();
itsFilter = filter;
if (!case_sensitive)
ToLower(itsFilter);
itsFilteredRealPositions.clear();
itsFilteredOptions.clear();
itsOptionsPtr = &itsOptions;
if (itsFilter.empty())
return;
for (size_t i = 0; i < beginning; i++)

View File

@@ -689,29 +689,15 @@ void Connection::GetList(TagList &v, mpd_TagItems type) const
char *item;
while ((item = mpd_getNextTag(itsConnection, type)) != NULL)
{
v.push_back(item);
if (item[0] != 0) // do not push empty item
v.push_back(item);
delete [] item;
}
mpd_finishCommand(itsConnection);
}
}
void Connection::GetArtists(TagList &v) const
{
if (isConnected)
{
mpd_sendListCommand(itsConnection, MPD_TABLE_ARTIST, NULL);
char *item;
while ((item = mpd_getNextArtist(itsConnection)) != NULL)
{
v.push_back(item);
delete [] item;
}
mpd_finishCommand(itsConnection);
}
}
void Connection::GetAlbums(string artist, TagList &v) const
void Connection::GetAlbums(const string &artist, TagList &v) const
{
if (isConnected)
{
@@ -719,7 +705,8 @@ void Connection::GetAlbums(string artist, TagList &v) const
char *item;
while ((item = mpd_getNextAlbum(itsConnection)) != NULL)
{
v.push_back(item);
if (item[0] != 0) // do not push empty item
v.push_back(item);
delete [] item;
}
mpd_finishCommand(itsConnection);
@@ -775,9 +762,8 @@ void Connection::CommitSearch(TagList &v) const
char *tag = NULL;
while ((tag = mpd_getNextTag(itsConnection, itsSearchedField)) != NULL)
{
string s_tag = tag;
if (v.empty() || v.back() != s_tag)
v.push_back(s_tag);
if (tag[0] != 0) // do not push empty item
v.push_back(tag);
delete [] tag;
}
mpd_finishCommand(itsConnection);

View File

@@ -180,8 +180,7 @@ namespace MPD
void GetPlaylists(TagList &) const;
void GetList(TagList &, mpd_TagItems) const;
void GetArtists(TagList &) const;
void GetAlbums(std::string, TagList &) const;
void GetAlbums(const std::string &, TagList &) const;
void GetDirectory(const std::string &, ItemList &) const;
void GetDirectoryRecursive(const std::string &, SongList &) const;
void GetSongs(const std::string &, SongList &) const;

View File

@@ -224,7 +224,6 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}";
conf.media_lib_album_format = "{(%y) }%b";
conf.tag_editor_album_format = "{(%y) }%b";
conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' ';
conf.pattern = "%n - %t";
@@ -506,11 +505,6 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (!v.empty())
conf.song_library_format = v;
}
else if (cl.find("media_library_album_format") != string::npos)
{
if (!v.empty())
conf.media_lib_album_format = v;
}
else if (cl.find("tag_editor_album_format") != string::npos)
{
if (!v.empty())

View File

@@ -108,7 +108,6 @@ struct ncmpcpp_config
std::string song_status_format;
std::string song_window_title_format;
std::string song_library_format;
std::string media_lib_album_format;
std::string tag_editor_album_format;
std::string external_editor;