Commit 9023ba4a authored by Max Kellermann's avatar Max Kellermann

PlaylistVector: use std::list

parent 83488848
......@@ -1358,7 +1358,7 @@ test_test_pcm_LDADD = \
test_TestQueuePriority_SOURCES = \
src/queue.c \
test/TestQueuePriority.c
test/TestQueuePriority.cxx
test_TestQueuePriority_LDADD = \
$(GLIB_LIBS)
......
......@@ -55,7 +55,6 @@ Directory::Directory()
{
INIT_LIST_HEAD(&children);
INIT_LIST_HEAD(&songs);
INIT_LIST_HEAD(&playlists);
path[0] = 0;
}
......@@ -64,15 +63,12 @@ Directory::Directory(const char *_path)
{
INIT_LIST_HEAD(&children);
INIT_LIST_HEAD(&songs);
INIT_LIST_HEAD(&playlists);
strcpy(path, _path);
}
Directory::~Directory()
{
playlist_vector_deinit(&playlists);
struct song *song, *ns;
directory_for_each_song_safe(song, ns, this)
song_free(song);
......@@ -318,9 +314,8 @@ Directory::Walk(bool recursive, const SongFilter *filter,
}
if (visit_playlist) {
PlaylistInfo *i;
directory_for_each_playlist(i, this)
if (!visit_playlist(*i, *this, error_r))
for (const PlaylistInfo &p : playlists)
if (!visit_playlist(p, *this, error_r))
return false;
}
......
......@@ -24,6 +24,7 @@
#include "util/list.h"
#include "gcc.h"
#include "DatabaseVisitor.hxx"
#include "PlaylistVector.hxx"
#include <glib.h>
#include <stdbool.h>
......@@ -44,12 +45,6 @@
#define directory_for_each_song_safe(pos, n, directory) \
list_for_each_entry_safe(pos, n, &directory->songs, siblings)
#define directory_for_each_playlist(pos, directory) \
list_for_each_entry(pos, &directory->playlists, siblings)
#define directory_for_each_playlist_safe(pos, n, directory) \
list_for_each_entry_safe(pos, n, &directory->playlists, siblings)
struct song;
struct db_visitor;
class SongFilter;
......@@ -81,7 +76,7 @@ struct Directory {
*/
struct list_head songs;
struct list_head playlists;
PlaylistVector playlists;
Directory *parent;
time_t mtime;
......@@ -179,7 +174,7 @@ public:
bool IsEmpty() const {
return list_empty(&children) &&
list_empty(&songs) &&
list_empty(&playlists);
playlists.empty();
}
gcc_pure
......
......@@ -72,7 +72,7 @@ directory_save(FILE *fp, const Directory *directory)
directory_for_each_song(song, directory)
song_save(fp, song);
playlist_vector_save(fp, &directory->playlists);
playlist_vector_save(fp, directory->playlists);
if (!directory->IsRoot())
fprintf(fp, DIRECTORY_END "%s\n", directory->GetPath());
......@@ -168,7 +168,7 @@ directory_load(FILE *fp, Directory *directory,
buffer */
char *name = g_strdup(line + sizeof(PLAYLIST_META_BEGIN) - 1);
if (!playlist_metadata_load(fp, &directory->playlists,
if (!playlist_metadata_load(fp, directory->playlists,
name, buffer, error)) {
g_free(name);
return false;
......
......@@ -36,18 +36,17 @@ playlist_database_quark(void)
}
void
playlist_vector_save(FILE *fp, const struct list_head *pv)
playlist_vector_save(FILE *fp, const PlaylistVector &pv)
{
PlaylistInfo *pm;
playlist_vector_for_each(pm, pv)
for (const PlaylistInfo &pi : pv)
fprintf(fp, PLAYLIST_META_BEGIN "%s\n"
"mtime: %li\n"
"playlist_end\n",
pm->name.c_str(), (long)pm->mtime);
pi.name.c_str(), (long)pi.mtime);
}
bool
playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
playlist_metadata_load(FILE *fp, PlaylistVector &pv, const char *name,
GString *buffer, GError **error_r)
{
PlaylistInfo pm(name, 0);
......@@ -76,6 +75,6 @@ playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
}
}
playlist_vector_update_or_add(pv, std::move(pm));
pv.UpdateOrInsert(std::move(pm));
return true;
}
......@@ -27,13 +27,13 @@
#define PLAYLIST_META_BEGIN "playlist_begin: "
struct list_head;
class PlaylistVector;
void
playlist_vector_save(FILE *fp, const struct list_head *pv);
playlist_vector_save(FILE *fp, const PlaylistVector &pv);
bool
playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
playlist_metadata_load(FILE *fp, PlaylistVector &pv, const char *name,
GString *buffer, GError **error_r);
#endif
......@@ -22,6 +22,7 @@
#include "check.h"
#include "util/list.h"
#include "gcc.h"
#include <string>
......@@ -40,6 +41,18 @@ struct PlaylistInfo {
time_t mtime;
class CompareName {
const char *const name;
public:
constexpr CompareName(const char *_name):name(_name) {}
gcc_pure
bool operator()(const PlaylistInfo &pi) const {
return pi.name.compare(name) == 0;
}
};
template<typename N>
PlaylistInfo(N &&_name, time_t _mtime)
:name(std::forward<N>(_name)), mtime(_mtime) {}
......
......@@ -21,71 +21,48 @@
#include "PlaylistVector.hxx"
#include "DatabaseLock.hxx"
#include <algorithm>
#include <assert.h>
#include <string.h>
#include <glib.h>
void
playlist_vector_deinit(struct list_head *pv)
{
assert(pv != NULL);
PlaylistInfo *pm, *n;
playlist_vector_for_each_safe(pm, n, pv)
delete pm;
}
PlaylistInfo *
playlist_vector_find(struct list_head *pv, const char *name)
PlaylistVector::iterator
PlaylistVector::find(const char *name)
{
assert(holding_db_lock());
assert(pv != NULL);
assert(name != NULL);
PlaylistInfo *pm;
playlist_vector_for_each(pm, pv)
if (pm->name.compare(name) == 0)
return pm;
return NULL;
}
void
playlist_vector_add(struct list_head *pv, PlaylistInfo &&pi)
{
assert(holding_db_lock());
PlaylistInfo *pm = new PlaylistInfo(std::move(pi));
list_add_tail(&pm->siblings, pv);
return std::find_if(begin(), end(),
PlaylistInfo::CompareName(name));
}
bool
playlist_vector_update_or_add(struct list_head *pv, PlaylistInfo &&pi)
PlaylistVector::UpdateOrInsert(PlaylistInfo &&pi)
{
assert(holding_db_lock());
PlaylistInfo *pm = playlist_vector_find(pv, pi.name.c_str());
if (pm != NULL) {
if (pi.mtime == pm->mtime)
auto i = find(pi.name.c_str());
if (i != end()) {
if (pi.mtime == i->mtime)
return false;
pm->mtime = pi.mtime;
i->mtime = pi.mtime;
} else
playlist_vector_add(pv, std::move(pi));
push_back(std::move(pi));
return true;
}
bool
playlist_vector_remove(struct list_head *pv, const char *name)
PlaylistVector::erase(const char *name)
{
assert(holding_db_lock());
PlaylistInfo *pm = playlist_vector_find(pv, name);
if (pm == NULL)
auto i = find(name);
if (i == end())
return false;
list_del(&pm->siblings);
delete pm;
erase(i);
return true;
}
......@@ -21,43 +21,35 @@
#define MPD_PLAYLIST_VECTOR_HXX
#include "PlaylistInfo.hxx"
#include "util/list.h"
#include <sys/time.h>
#define playlist_vector_for_each(pos, head) \
list_for_each_entry(pos, head, siblings)
#define playlist_vector_for_each_safe(pos, n, head) \
list_for_each_entry_safe(pos, n, head, siblings)
void
playlist_vector_deinit(struct list_head *pv);
/**
* Caller must lock the #db_mutex.
*/
PlaylistInfo *
playlist_vector_find(struct list_head *pv, const char *name);
/**
* Caller must lock the #db_mutex.
*/
void
playlist_vector_add(struct list_head *pv, PlaylistInfo &&pi);
/**
* Caller must lock the #db_mutex.
*
* @return true if the vector or one of its items was modified
*/
bool
playlist_vector_update_or_add(struct list_head *pv, PlaylistInfo &&pi);
/**
* Caller must lock the #db_mutex.
*/
bool
playlist_vector_remove(struct list_head *pv, const char *name);
#include "gcc.h"
#include <list>
class PlaylistVector : protected std::list<PlaylistInfo> {
protected:
/**
* Caller must lock the #db_mutex.
*/
gcc_pure
iterator find(const char *name);
public:
using std::list<PlaylistInfo>::empty;
using std::list<PlaylistInfo>::begin;
using std::list<PlaylistInfo>::end;
using std::list<PlaylistInfo>::erase;
/**
* Caller must lock the #db_mutex.
*
* @return true if the vector or one of its items was modified
*/
bool UpdateOrInsert(PlaylistInfo &&pi);
/**
* Caller must lock the #db_mutex.
*/
bool erase(const char *name);
};
#endif /* SONGVEC_H */
......@@ -96,7 +96,7 @@ delete_name_in(Directory *parent, const char *name)
modified = true;
}
playlist_vector_remove(&parent->playlists, name);
parent->playlists.erase(name);
db_unlock();
......
......@@ -158,14 +158,15 @@ purge_deleted_from_directory(Directory *directory)
g_free(path);
}
PlaylistInfo *pm, *np;
directory_for_each_playlist_safe(pm, np, directory) {
if (!directory_child_is_regular(directory, pm->name.c_str())) {
for (auto i = directory->playlists.begin(),
end = directory->playlists.end();
i != end;) {
if (!directory_child_is_regular(directory, i->name.c_str())) {
db_lock();
playlist_vector_remove(&directory->playlists,
pm->name.c_str());
i = directory->playlists.erase(i);
db_unlock();
}
} else
++i;
}
}
......@@ -217,8 +218,7 @@ update_playlist_file2(Directory *directory,
PlaylistInfo pi(name, st->st_mtime);
db_lock();
if (playlist_vector_update_or_add(&directory->playlists,
std::move(pi)))
if (directory->playlists.UpdateOrInsert(std::move(pi)))
modified = true;
db_unlock();
return true;
......
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