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}" #song_library_format = "{%n - }{%t}|{%f}"
# #
#media_library_album_format = "{(%y) }%b"
#
#tag_editor_album_format = "{(%y) }%b" #tag_editor_album_format = "{(%y) }%b"
# #
#browser_playlist_prefix = "$2playlist$9 " #browser_playlist_prefix = "$2playlist$9 "

View File

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

View File

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

View File

@@ -76,6 +76,11 @@ namespace NCurses
bool isStatic; 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 *>::iterator option_iterator;
typedef typename std::vector<Option *>::const_iterator option_const_iterator; typedef typename std::vector<Option *>::const_iterator option_const_iterator;
@@ -128,6 +133,14 @@ namespace NCurses
virtual void Reset(); virtual void Reset();
virtual void Clear(bool clrscr = 1); 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 SetSelectPrefix(Buffer *b) { itsSelectedPrefix = b; }
void SetSelectSuffix(Buffer *b) { itsSelectedSuffix = b; } void SetSelectSuffix(Buffer *b) { itsSelectedSuffix = b; }
@@ -149,6 +162,8 @@ namespace NCurses
virtual Menu<T> *EmptyClone() const; virtual Menu<T> *EmptyClone() const;
protected: protected:
void ClearFiltered();
ItemDisplayer itsItemDisplayer; ItemDisplayer itsItemDisplayer;
void *itsItemDisplayerUserdata; void *itsItemDisplayerUserdata;
GetStringFunction itsGetStringFunction; GetStringFunction itsGetStringFunction;
@@ -462,14 +477,20 @@ template <class T> void NCurses::Menu<T>::Reset()
itsBeginning = 0; 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) template <class T> void NCurses::Menu<T>::Clear(bool clrscr)
{ {
for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++)
delete *it; delete *it;
itsOptions.clear(); itsOptions.clear();
itsFilteredOptions.clear(); ClearFiltered();
itsFilteredRealPositions.clear();
itsFilter.clear();
itsOptionsPtr = &itsOptions; itsOptionsPtr = &itsOptions;
if (clrscr) if (clrscr)
Window::Clear(); Window::Clear();
@@ -557,12 +578,10 @@ template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter,
{ {
if (filter == itsFilter) if (filter == itsFilter)
return; return;
ClearFiltered();
itsFilter = filter; itsFilter = filter;
if (!case_sensitive) if (!case_sensitive)
ToLower(itsFilter); ToLower(itsFilter);
itsFilteredRealPositions.clear();
itsFilteredOptions.clear();
itsOptionsPtr = &itsOptions;
if (itsFilter.empty()) if (itsFilter.empty())
return; return;
for (size_t i = 0; i < beginning; i++) 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; char *item;
while ((item = mpd_getNextTag(itsConnection, type)) != NULL) 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; delete [] item;
} }
mpd_finishCommand(itsConnection); mpd_finishCommand(itsConnection);
} }
} }
void Connection::GetArtists(TagList &v) const void Connection::GetAlbums(const string &artist, 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
{ {
if (isConnected) if (isConnected)
{ {
@@ -719,7 +705,8 @@ void Connection::GetAlbums(string artist, TagList &v) const
char *item; char *item;
while ((item = mpd_getNextAlbum(itsConnection)) != NULL) 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; delete [] item;
} }
mpd_finishCommand(itsConnection); mpd_finishCommand(itsConnection);
@@ -775,9 +762,8 @@ void Connection::CommitSearch(TagList &v) const
char *tag = NULL; char *tag = NULL;
while ((tag = mpd_getNextTag(itsConnection, itsSearchedField)) != NULL) while ((tag = mpd_getNextTag(itsConnection, itsSearchedField)) != NULL)
{ {
string s_tag = tag; if (tag[0] != 0) // do not push empty item
if (v.empty() || v.back() != s_tag) v.push_back(tag);
v.push_back(s_tag);
delete [] tag; delete [] tag;
} }
mpd_finishCommand(itsConnection); mpd_finishCommand(itsConnection);

View File

@@ -180,8 +180,7 @@ namespace MPD
void GetPlaylists(TagList &) const; void GetPlaylists(TagList &) const;
void GetList(TagList &, mpd_TagItems) const; void GetList(TagList &, mpd_TagItems) const;
void GetArtists(TagList &) const; void GetAlbums(const std::string &, TagList &) const;
void GetAlbums(std::string, TagList &) const;
void GetDirectory(const std::string &, ItemList &) const; void GetDirectory(const std::string &, ItemList &) const;
void GetDirectoryRecursive(const std::string &, SongList &) const; void GetDirectoryRecursive(const std::string &, SongList &) const;
void GetSongs(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_status_format = "{(%l) }{%a - }{%t}|{%f}";
conf.song_window_title_format = "{%a - }{%t}|{%f}"; conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}"; conf.song_library_format = "{%n - }{%t}|{%f}";
conf.media_lib_album_format = "{(%y) }%b";
conf.tag_editor_album_format = "{(%y) }%b"; conf.tag_editor_album_format = "{(%y) }%b";
conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' '; conf.browser_playlist_prefix << clRed << "(playlist)" << clEnd << ' ';
conf.pattern = "%n - %t"; conf.pattern = "%n - %t";
@@ -506,11 +505,6 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (!v.empty()) if (!v.empty())
conf.song_library_format = v; 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) else if (cl.find("tag_editor_album_format") != string::npos)
{ {
if (!v.empty()) if (!v.empty())

View File

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