summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2016-11-22 12:25:52 +0100
committerMax Kellermann <max@musicpd.org>2016-11-22 16:49:31 +0100
commit95e2bec215b17e11601edf5456eaf0e73ccc944d (patch)
tree7b1471f36e519ec9a0ff2970401b08ada677cf46 /src
parent72c96052b4f4c18959fe0fb374bc8c17cb9c19fe (diff)
decoder/DecoderPlugin: container_scan() returns forward_list<DetachedSong>
Speed up container_scan() again, by eliminating the need to call scan_file() for each item.
Diffstat (limited to 'src')
-rw-r--r--src/db/update/Container.cxx31
-rw-r--r--src/decoder/DecoderPlugin.hxx4
-rw-r--r--src/decoder/plugins/GmeDecoderPlugin.cxx17
-rw-r--r--src/decoder/plugins/SidplayDecoderPlugin.cxx22
4 files changed, 40 insertions, 34 deletions
diff --git a/src/db/update/Container.cxx b/src/db/update/Container.cxx
index c56ed1eb8..b21c4adb4 100644
--- a/src/db/update/Container.cxx
+++ b/src/db/update/Container.cxx
@@ -20,6 +20,7 @@
#include "config.h" /* must be first for large file support */
#include "Walk.hxx"
#include "UpdateDomain.hxx"
+#include "DetachedSong.hxx"
#include "db/DatabaseLock.hxx"
#include "db/plugins/simple/Directory.hxx"
#include "db/plugins/simple/Song.hxx"
@@ -28,8 +29,6 @@
#include "decoder/DecoderList.hxx"
#include "fs/AllocatedPath.hxx"
#include "storage/FileInfo.hxx"
-#include "tag/TagHandler.hxx"
-#include "tag/TagBuilder.hxx"
#include "Log.hxx"
#include "util/AllocatedString.hxx"
@@ -97,34 +96,21 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
}
try {
- const auto v = plugin.container_scan(pathname);
+ auto v = plugin.container_scan(pathname);
if (v.empty()) {
editor.LockDeleteDirectory(contdir);
return false;
}
- TagBuilder tag_builder;
- for (const auto &vtrack : v) {
- Song *song = Song::NewFile(vtrack.c_str(), *contdir);
+ for (auto &vtrack : v) {
+ Song *song = Song::NewFrom(std::move(vtrack),
+ *contdir);
// shouldn't be necessary but it's there..
song->mtime = info.mtime;
- try {
- const auto vtrack_fs =
- AllocatedPath::FromUTF8Throw(vtrack.c_str());
-
- const auto child_path_fs = AllocatedPath::Build(pathname,
- vtrack_fs);
- plugin.ScanFile(child_path_fs,
- add_tag_handler, &tag_builder);
- } catch (const std::runtime_error &e) {
- song->Free();
- LogError(e);
- continue;
- }
-
- tag_builder.Commit(song->tag);
+ FormatDefault(update_domain, "added %s/%s",
+ contdir->GetPath(), song->uri);
{
const ScopeDatabaseLock protect;
@@ -132,9 +118,6 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
}
modified = true;
-
- FormatDefault(update_domain, "added %s/%s",
- directory.GetPath(), vtrack.c_str());
}
} catch (const std::runtime_error &e) {
editor.LockDeleteDirectory(contdir);
diff --git a/src/decoder/DecoderPlugin.hxx b/src/decoder/DecoderPlugin.hxx
index ec24a115f..d36bb4002 100644
--- a/src/decoder/DecoderPlugin.hxx
+++ b/src/decoder/DecoderPlugin.hxx
@@ -23,13 +23,13 @@
#include "Compiler.h"
#include <forward_list>
-#include <string>
struct ConfigBlock;
class InputStream;
struct TagHandler;
class Path;
class DecoderClient;
+class DetachedSong;
struct DecoderPlugin {
const char *name;
@@ -93,7 +93,7 @@ struct DecoderPlugin {
* a filename for every single track;
* do not include full pathname here, just the "virtual" file
*/
- std::forward_list<std::string> (*container_scan)(Path path_fs);
+ std::forward_list<DetachedSong> (*container_scan)(Path path_fs);
/* last element in these arrays must always be a nullptr: */
const char *const*suffixes;
diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx
index f3813d475..cd58bc06a 100644
--- a/src/decoder/plugins/GmeDecoderPlugin.cxx
+++ b/src/decoder/plugins/GmeDecoderPlugin.cxx
@@ -22,7 +22,9 @@
#include "../DecoderAPI.hxx"
#include "config/Block.cxx"
#include "CheckAudioFormat.hxx"
+#include "DetachedSong.hxx"
#include "tag/TagHandler.hxx"
+#include "tag/TagBuilder.hxx"
#include "fs/Path.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/ScopeExit.hxx"
@@ -266,10 +268,10 @@ gme_scan_file(Path path_fs,
return ScanMusicEmu(emu, container.track, handler, handler_ctx);
}
-static std::forward_list<std::string>
+static std::forward_list<DetachedSong>
gme_container_scan(Path path_fs)
{
- std::forward_list<std::string> list;
+ std::forward_list<DetachedSong> list;
Music_Emu *emu;
const char *gme_err = gme_open_file(path_fs.c_str(), &emu,
@@ -279,20 +281,27 @@ gme_container_scan(Path path_fs)
return list;
}
+ AtScopeExit(emu) { gme_delete(emu); };
+
const unsigned num_songs = gme_track_count(emu);
- gme_delete(emu);
/* if it only contains a single tune, don't treat as container */
if (num_songs < 2)
return list;
const char *subtune_suffix = uri_get_suffix(path_fs.c_str());
+ TagBuilder tag_builder;
+
auto tail = list.before_begin();
for (unsigned i = 1; i <= num_songs; ++i) {
+ ScanMusicEmu(emu, i,
+ add_tag_handler, &tag_builder);
+
char track_name[64];
snprintf(track_name, sizeof(track_name),
SUBTUNE_PREFIX "%03u.%s", i, subtune_suffix);
- tail = list.emplace_after(tail, track_name);
+ tail = list.emplace_after(tail, track_name,
+ tag_builder.Commit());
}
return list;
diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx
index 151a73914..b7edd9a95 100644
--- a/src/decoder/plugins/SidplayDecoderPlugin.cxx
+++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx
@@ -21,6 +21,8 @@
#include "SidplayDecoderPlugin.hxx"
#include "../DecoderAPI.hxx"
#include "tag/TagHandler.hxx"
+#include "tag/TagBuilder.hxx"
+#include "DetachedSong.hxx"
#include "fs/Path.hxx"
#include "fs/AllocatedPath.hxx"
#include "util/Macros.hxx"
@@ -467,12 +469,16 @@ sidplay_scan_file(Path path_fs,
return true;
}
-static std::forward_list<std::string>
+static std::forward_list<DetachedSong>
sidplay_container_scan(Path path_fs)
{
- std::forward_list<std::string> list;
+ std::forward_list<DetachedSong> list;
- SidTune tune(path_fs.c_str(), nullptr, true);
+#ifdef HAVE_SIDPLAYFP
+ SidTune tune(path_fs.c_str());
+#else
+ SidTuneMod tune(path_fs.c_str());
+#endif
if (!tune.getStatus())
return list;
@@ -489,13 +495,21 @@ sidplay_container_scan(Path path_fs)
if(!all_files_are_containers && n_tracks < 2)
return list;
+ TagBuilder tag_builder;
+
auto tail = list.before_begin();
for (unsigned i = 1; i <= n_tracks; ++i) {
+ tune.selectSong(i);
+
+ ScanSidTuneInfo(info, i, n_tracks,
+ add_tag_handler, &tag_builder);
+
char track_name[32];
/* Construct container/tune path names, eg.
Delta.sid/tune_001.sid */
sprintf(track_name, SUBTUNE_PREFIX "%03u.sid", i);
- tail = list.emplace_after(tail, track_name);
+ tail = list.emplace_after(tail, track_name,
+ tag_builder.Commit());
}
return list;