Commit d2cf7402 authored by Max Kellermann's avatar Max Kellermann

Song: embed the Tag object statically into class Song

Reduces overhead because we need to manage only one memory allocation. According to valgrind/massif, we save 7%.
parent bc966577
......@@ -39,9 +39,7 @@ typedef std::set<const char *, StringLess> StringSet;
static bool
CollectTags(StringSet &set, TagType tag_type, Song &song)
{
Tag *tag = song.tag;
if (tag == nullptr)
return true;
const Tag *tag = &song.tag;
bool found = false;
for (unsigned i = 0; i < tag->num_items; ++i) {
......@@ -108,8 +106,7 @@ StatsVisitSong(DatabaseStats &stats, StringSet &artists, StringSet &albums,
{
++stats.song_count;
if (song.tag != nullptr)
StatsVisitTag(stats, artists, albums, *song.tag);
StatsVisitTag(stats, artists, albums, song.tag);
return true;
}
......
......@@ -70,7 +70,7 @@ PrintSongBrief(Client &client, const Song &song)
{
song_print_uri(client, song);
if (song.tag != nullptr && song.tag->has_playlist)
if (song.tag.has_playlist)
/* this song file has an embedded CUE sheet */
print_playlist_in_directory(client, song.parent, song.uri);
......@@ -82,7 +82,7 @@ PrintSongFull(Client &client, const Song &song)
{
song_print_info(client, song);
if (song.tag != nullptr && song.tag->has_playlist)
if (song.tag.has_playlist)
/* this song file has an embedded CUE sheet */
print_playlist_in_directory(client, song.parent, song.uri);
......
......@@ -25,7 +25,7 @@
DetachedSong::DetachedSong(const Song &other)
:uri(other.GetURI().c_str()),
tag(other.tag != nullptr ? *other.tag : Tag()),
tag(other.tag),
mtime(other.mtime),
start_ms(other.start_ms), end_ms(other.end_ms) {}
......
......@@ -49,9 +49,7 @@ UpdatePlaylistSong(const Database &db, DetachedSong &song)
}
song.SetLastModified(original->mtime);
if (original->tag != nullptr)
song.SetTag(*original->tag);
song.SetTag(original->tag);
db.ReturnSong(original);
return true;
......
......@@ -29,14 +29,13 @@
#include <stdlib.h>
inline Song::Song(const char *_uri, size_t uri_length, Directory *_parent)
:tag(nullptr), parent(_parent), mtime(0), start_ms(0), end_ms(0)
:parent(_parent), mtime(0), start_ms(0), end_ms(0)
{
memcpy(uri, _uri, uri_length + 1);
}
inline Song::~Song()
{
delete tag;
}
static Song *
......@@ -57,7 +56,7 @@ Song *
Song::NewFrom(DetachedSong &&other, Directory *parent)
{
Song *song = song_alloc(other.GetURI(), parent);
song->tag = new Tag(std::move(other.WritableTag()));
song->tag = std::move(other.WritableTag());
song->mtime = other.GetLastModified();
song->start_ms = other.GetStartMS();
song->end_ms = other.GetEndMS();
......@@ -101,8 +100,8 @@ Song::GetDuration() const
if (end_ms > 0)
return (end_ms - start_ms) / 1000.0;
if (tag == nullptr)
if (tag.time <= 0)
return 0;
return tag->time - start_ms / 1000.0;
return tag.time - start_ms / 1000.0;
}
......@@ -21,6 +21,7 @@
#define MPD_SONG_HXX
#include "util/list.h"
#include "tag/Tag.hxx"
#include "Compiler.h"
#include <string>
......@@ -31,7 +32,6 @@
#define SONG_FILE "file: "
#define SONG_TIME "Time: "
struct Tag;
struct Directory;
class DetachedSong;
......@@ -49,7 +49,7 @@ struct Song {
*/
struct list_head siblings;
Tag *tag;
Tag tag;
/**
* The #Directory that contains this song. May be nullptr if
......
......@@ -149,7 +149,7 @@ SongFilter::Item::Match(const Song &song) const
return StringMatch(uri.c_str());
}
return song.tag != NULL && Match(*song.tag);
return Match(song.tag);
}
bool
......
......@@ -74,8 +74,7 @@ song_print_info(Client &client, const Song &song)
if (song.mtime > 0)
time_print(client, "Last-Modified", song.mtime);
if (song.tag != nullptr)
tag_print(client, *song.tag);
tag_print(client, song.tag);
}
void
......
......@@ -53,8 +53,7 @@ song_save(FILE *fp, const Song &song)
range_save(fp, song.start_ms, song.end_ms);
if (song.tag != nullptr)
tag_save(fp, *song.tag);
tag_save(fp, song.tag);
fprintf(fp, SONG_MTIME ": %li\n", (long)song.mtime);
fprintf(fp, SONG_END "\n");
......
......@@ -30,14 +30,6 @@ extern "C" {
#include <stdlib.h>
static const char *
tag_get_value_checked(const Tag *tag, TagType type)
{
return tag != nullptr
? tag->GetValue(type)
: nullptr;
}
static int
compare_utf8_string(const char *a, const char *b)
{
......@@ -55,11 +47,11 @@ compare_utf8_string(const char *a, const char *b)
* nullptr.
*/
static int
compare_string_tag_item(const Tag *a, const Tag *b,
compare_string_tag_item(const Tag &a, const Tag &b,
TagType type)
{
return compare_utf8_string(tag_get_value_checked(a, type),
tag_get_value_checked(b, type));
return compare_utf8_string(a.GetValue(type),
b.GetValue(type));
}
/**
......@@ -82,10 +74,10 @@ compare_number_string(const char *a, const char *b)
}
static int
compare_tag_item(const Tag *a, const Tag *b, TagType type)
compare_tag_item(const Tag &a, const Tag &b, TagType type)
{
return compare_number_string(tag_get_value_checked(a, type),
tag_get_value_checked(b, type));
return compare_number_string(a.GetValue(type),
b.GetValue(type));
}
/* Only used for sorting/searchin a songvec, not general purpose compares */
......
......@@ -98,8 +98,7 @@ Song::UpdateFile()
mtime = st.st_mtime;
delete tag;
tag = tag_builder.CommitNew();
tag_builder.Commit(tag);
return true;
}
......@@ -123,8 +122,7 @@ Song::UpdateFileInArchive()
if (!tag_stream_scan(path_fs.c_str(), full_tag_handler, &tag_builder))
return false;
delete tag;
tag = tag_builder.CommitNew();
tag_builder.Commit(tag);
return true;
}
......
......@@ -113,10 +113,7 @@ update_container_file(Directory &directory,
plugin.ScanFile(child_path_fs.c_str(),
add_tag_handler, &tag_builder);
if (tag_builder.IsDefined())
song->tag = tag_builder.CommitNew();
else
tag_builder.Clear();
tag_builder.Commit(song->tag);
db_lock();
contdir->AddSong(song);
......
......@@ -524,7 +524,7 @@ Convert(const struct mpd_song *song)
for (const auto *i = &tag_table[0]; i->d != TAG_NUM_OF_ITEM_TYPES; ++i)
Copy(tag, i->d, song, i->s);
s->tag = tag.CommitNew();
tag.Commit(s->tag);
return s;
}
......
......@@ -205,7 +205,7 @@ upnpItemToSong(UPnPDirObject &&dirent, const char *uri)
uri = dirent.url.c_str();
Song *s = Song::NewFile(uri, nullptr);
s->tag = new Tag(std::move(dirent.tag));
s->tag = std::move(dirent.tag);
return s;
}
......
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