From 52ee132d92d4a04d31bbbdeb7c6c0077bd2a2828 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 5 Sep 2013 19:11:50 +0200 Subject: TagHandler: use a TagBuilder internally Reduce heap allocator overhead. --- src/SongUpdate.cxx | 26 +++++++++++++++----------- src/UpdateContainer.cxx | 11 ++++++++--- src/decoder/FlacMetadata.cxx | 5 ++++- src/decoder/OpusDecoderPlugin.cxx | 11 +++++++---- src/decoder/VorbisComments.cxx | 15 ++++++--------- src/tag/TagHandler.cxx | 14 +++++++------- src/tag/TagHandler.hxx | 4 ++-- src/tag/TagId3.cxx | 16 ++++++---------- 8 files changed, 55 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index 8e9768d55..4c5f35c78 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -29,6 +29,7 @@ #include "DecoderPlugin.hxx" #include "DecoderList.hxx" #include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include "tag/TagHandler.hxx" #include "tag/TagId3.hxx" #include "tag/ApeTag.hxx" @@ -113,15 +114,15 @@ Song::UpdateFile() Mutex mutex; Cond cond; + TagBuilder tag_builder; + do { /* load file tag */ - tag = new Tag(); if (decoder_plugin_scan_file(plugin, path_fs.c_str(), - &full_tag_handler, tag)) + &full_tag_handler, &tag_builder)) break; - delete tag; - tag = nullptr; + tag_builder.Clear(); /* fall back to stream tag */ if (plugin->scan_stream != NULL) { @@ -134,14 +135,12 @@ Song::UpdateFile() /* now try the stream_tag() method */ if (is != NULL) { - tag = new Tag(); if (decoder_plugin_scan_stream(plugin, is, &full_tag_handler, - tag)) + &tag_builder)) break; - delete tag; - tag = nullptr; + tag_builder.Clear(); is->LockSeek(0, SEEK_SET, IgnoreError()); } @@ -153,10 +152,15 @@ Song::UpdateFile() if (is != NULL) is->Close(); - if (tag != nullptr && tag->IsEmpty()) - tag_scan_fallback(path_fs.c_str(), &full_tag_handler, tag); + if (!tag_builder.IsDefined()) + return false; + + if (tag_builder.IsEmpty()) + tag_scan_fallback(path_fs.c_str(), &full_tag_handler, + &tag_builder); - return tag != nullptr; + tag = tag_builder.Commit(); + return true; } bool diff --git a/src/UpdateContainer.cxx b/src/UpdateContainer.cxx index a24f38830..572f8cc67 100644 --- a/src/UpdateContainer.cxx +++ b/src/UpdateContainer.cxx @@ -28,7 +28,7 @@ #include "Mapper.hxx" #include "fs/Path.hxx" #include "tag/TagHandler.hxx" -#include "tag/Tag.hxx" +#include "tag/TagBuilder.hxx" #include @@ -86,6 +86,7 @@ update_container_file(Directory *directory, char *vtrack; unsigned int tnum = 0; + TagBuilder tag_builder; while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != NULL) { Song *song = Song::NewFile(vtrack, contdir); @@ -95,9 +96,13 @@ update_container_file(Directory *directory, const Path child_path_fs = map_directory_child_fs(contdir, vtrack); - song->tag = new Tag(); decoder_plugin_scan_file(plugin, child_path_fs.c_str(), - &add_tag_handler, song->tag); + &add_tag_handler, &tag_builder); + + if (tag_builder.IsDefined()) + song->tag = tag_builder.Commit(); + else + tag_builder.Clear(); db_lock(); contdir->AddSong(song); diff --git a/src/decoder/FlacMetadata.cxx b/src/decoder/FlacMetadata.cxx index a27fec5d2..49e4851e8 100644 --- a/src/decoder/FlacMetadata.cxx +++ b/src/decoder/FlacMetadata.cxx @@ -23,6 +23,7 @@ #include "tag/Tag.hxx" #include "tag/TagHandler.hxx" #include "tag/TagTable.hxx" +#include "tag/TagBuilder.hxx" #include "replay_gain_info.h" #include @@ -231,7 +232,9 @@ void flac_vorbis_comments_to_tag(Tag &tag, const FLAC__StreamMetadata_VorbisComment *comment) { - flac_scan_comments(comment, &add_tag_handler, &tag); + TagBuilder tag_builder; + flac_scan_comments(comment, &add_tag_handler, &tag_builder); + tag_builder.Commit(tag); } void diff --git a/src/decoder/OpusDecoderPlugin.cxx b/src/decoder/OpusDecoderPlugin.cxx index 9d852102b..c757d66ef 100644 --- a/src/decoder/OpusDecoderPlugin.cxx +++ b/src/decoder/OpusDecoderPlugin.cxx @@ -28,6 +28,7 @@ #include "OggCodec.hxx" #include "CheckAudioFormat.hxx" #include "tag/TagHandler.hxx" +#include "tag/TagBuilder.hxx" #include "InputStream.hxx" #include "util/Error.hxx" @@ -222,14 +223,16 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet) inline enum decoder_command MPDOpusDecoder::HandleTags(const ogg_packet &packet) { - Tag tag; + TagBuilder tag_builder; enum decoder_command cmd; if (ScanOpusTags(packet.packet, packet.bytes, - &add_tag_handler, &tag) && - !tag.IsEmpty()) + &add_tag_handler, &tag_builder) && + !tag_builder.IsEmpty()) { + Tag tag; + tag_builder.Commit(tag); cmd = decoder_tag(decoder, input_stream, std::move(tag)); - else + } else cmd = decoder_get_command(decoder); return cmd; diff --git a/src/decoder/VorbisComments.cxx b/src/decoder/VorbisComments.cxx index 48c603ea4..c8eeb09cd 100644 --- a/src/decoder/VorbisComments.cxx +++ b/src/decoder/VorbisComments.cxx @@ -23,6 +23,7 @@ #include "tag/Tag.hxx" #include "tag/TagTable.hxx" #include "tag/TagHandler.hxx" +#include "tag/TagBuilder.hxx" #include "replay_gain_info.h" #include @@ -138,13 +139,9 @@ vorbis_comments_scan(char **comments, Tag * vorbis_comments_to_tag(char **comments) { - Tag *tag = new Tag(); - vorbis_comments_scan(comments, &add_tag_handler, tag); - - if (tag->IsEmpty()) { - delete tag; - tag = NULL; - } - - return tag; + TagBuilder tag_builder; + vorbis_comments_scan(comments, &add_tag_handler, &tag_builder); + return tag_builder.IsEmpty() + ? nullptr + : tag_builder.Commit(); } diff --git a/src/tag/TagHandler.cxx b/src/tag/TagHandler.cxx index 055fae49a..859f92b20 100644 --- a/src/tag/TagHandler.cxx +++ b/src/tag/TagHandler.cxx @@ -19,24 +19,24 @@ #include "config.h" #include "TagHandler.hxx" -#include "Tag.hxx" +#include "TagBuilder.hxx" #include static void add_tag_duration(unsigned seconds, void *ctx) { - Tag *tag = (Tag *)ctx; + TagBuilder &tag = *(TagBuilder *)ctx; - tag->time = seconds; + tag.SetTime(seconds); } static void add_tag_tag(enum tag_type type, const char *value, void *ctx) { - Tag *tag = (Tag *)ctx; + TagBuilder &tag = *(TagBuilder *)ctx; - tag->AddItem(type, value); + tag.AddItem(type, value); } const struct tag_handler add_tag_handler = { @@ -48,10 +48,10 @@ const struct tag_handler add_tag_handler = { static void full_tag_pair(const char *name, gcc_unused const char *value, void *ctx) { - Tag *tag = (Tag *)ctx; + TagBuilder &tag = *(TagBuilder *)ctx; if (g_ascii_strcasecmp(name, "cuesheet") == 0) - tag->has_playlist = true; + tag.SetHasPlaylist(true); } const struct tag_handler full_tag_handler = { diff --git a/src/tag/TagHandler.hxx b/src/tag/TagHandler.hxx index 3303dd27e..36871c962 100644 --- a/src/tag/TagHandler.hxx +++ b/src/tag/TagHandler.hxx @@ -86,13 +86,13 @@ tag_handler_invoke_pair(const struct tag_handler *handler, void *ctx, } /** - * This #tag_handler implementation adds tag values to a #tag object + * This #tag_handler implementation adds tag values to a #TagBuilder object * (casted from the context pointer). */ extern const struct tag_handler add_tag_handler; /** - * This #tag_handler implementation adds tag values to a #tag object + * This #tag_handler implementation adds tag values to a #TagBuilder object * (casted from the context pointer), and supports the has_playlist * attribute. */ diff --git a/src/tag/TagId3.cxx b/src/tag/TagId3.cxx index 0bea92bb7..0fc1b01db 100644 --- a/src/tag/TagId3.cxx +++ b/src/tag/TagId3.cxx @@ -22,6 +22,7 @@ #include "TagHandler.hxx" #include "TagTable.hxx" #include "Tag.hxx" +#include "TagBuilder.hxx" #include "util/Error.hxx" #include "ConfigGlobal.hxx" @@ -387,16 +388,11 @@ scan_id3_tag(struct id3_tag *tag, Tag * tag_id3_import(struct id3_tag *tag) { - Tag *ret = new Tag(); - - scan_id3_tag(tag, &add_tag_handler, ret); - - if (ret->IsEmpty()) { - delete ret; - ret = nullptr; - } - - return ret; + TagBuilder tag_builder; + scan_id3_tag(tag, &add_tag_handler, &tag_builder); + return tag_builder.IsEmpty() + ? nullptr + : tag_builder.Commit(); } static int -- cgit v1.2.3