speed up browsing media library

the way media library was searching for albums
was wrong and by the way totally inefficient.
master
Andrzej Rybczak 17 years ago
parent 93fd687ec1
commit a4599fffe7
  1. 2
      doc/config
  2. 31
      src/media_library.cpp
  3. 1
      src/media_library.h
  4. 31
      src/menu.h
  5. 24
      src/mpdpp.cpp
  6. 3
      src/mpdpp.h
  7. 6
      src/settings.cpp
  8. 1
      src/settings.h

@ -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 "

@ -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);
for (SongList::const_iterator j = l.begin(); j != l.end(); j++)
{
utf_to_locale(*it); utf_to_locale(*it);
(*j)->Localize(); if (l.empty())
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()); 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();
} }

@ -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;

@ -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++)

@ -689,6 +689,7 @@ 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)
{ {
if (item[0] != 0) // do not push empty item
v.push_back(item); v.push_back(item);
delete [] item; delete [] item;
} }
@ -696,22 +697,7 @@ void Connection::GetList(TagList &v, mpd_TagItems type) const
} }
} }
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,6 +705,7 @@ void Connection::GetAlbums(string artist, TagList &v) const
char *item; char *item;
while ((item = mpd_getNextAlbum(itsConnection)) != NULL) while ((item = mpd_getNextAlbum(itsConnection)) != NULL)
{ {
if (item[0] != 0) // do not push empty item
v.push_back(item); v.push_back(item);
delete [] item; delete [] item;
} }
@ -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);

@ -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;

@ -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())

@ -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;

Loading…
Cancel
Save