(wip) song/DirectorySongFilter: new filter#2419
(wip) song/DirectorySongFilter: new filter#2419thjbdvlt wants to merge 4 commits intoMusicPlayerDaemon:masterfrom
Conversation
src/song/LightSong.hxx
Outdated
| } | ||
|
|
||
| [[gnu::pure]] | ||
| std::string GetDirectory() const noexcept { |
There was a problem hiding this comment.
This method creates an allocated copy of the directory field, but I find that rather useless, what's the point of that copy? I think the whole method is not useful at all. You create a copy on the heap only to get a C string, but you already have a C string.
There was a problem hiding this comment.
That's right, i remove the allocation.
I actually added the method mostly to create a string if directory is null:
if (directory == nullptr)
return std::string("");But it seems rather useless, I remove the method. It's also prettier with ternary operator:
return StringIsEqual(value.c_str(), song.directory == nullptr ? "" : song.directory);|
Please add protocol documentation |
|
I'm really sorry: I thought it was easier to implement that it's actually. Thus I thought that my kinda superficial C++ knowledge would do it; it doesn't. |
|
I forgot about I thought this PR was good, I just didn't like the unnecessary allocation. |
|
But it (or My directory filter is much slower. I'm probably not using MPD protocol very well (there's a loop in which I call |
|
True, your code is completely unoptimized. It's a naive approach - and it works. I like naive code that just works! But of course, it's at the same time somewhat clumsy. A search with your filter will traverse the whole database and check the URI of each and every song. The right approach would be to go to that one First step towards optimizing it: Next: in For experts: make your new feature work with |
|
Thank you so much! Your hints gave me good insights into the code. This leads to a solution that's both faster and more concise. Now I have a new question. To access for (const auto &i : filter->GetItems()) {
const auto *f = dynamic_cast<const BaseSongFilter *>(i.get());
if (f != nullptr && !f->recursive) {
recursive = false;
break;
}
}I can either make |
|
Don't use negated names. Call it |
src/db/Selection.cxx
Outdated
|
|
||
| /* BaseSongFilter may have an explicit non-recursive flag set */ | ||
| if (recursive && filter != nullptr) { | ||
| for (const auto &i : filter->GetItems()) { |
There was a problem hiding this comment.
I don't like that this traverses the filter list again (was already done by SongFilter::GetBase()). This seems fragile because you never know if the two copies of that loop are looking at the same BaseSongFilter instance.
Maybe refactor SongFilter::GetBase() to something that returns both the base directory and the recursive flag? Something like:
struct Base { const char *uri; bool recursive; };
Base GetBase() ...
There was a problem hiding this comment.
Great! I didn't like to do the same loop twice, so I'm doing this.
It also avoids a SongBase::IsRecursive() (only BaseSongFilter::IsRecursive()).
|
When you do fixups for unmerged commits, please don't add fixup commits on top; instead, amend the existing commit. |
src/song/BaseSongFilter.hxx
Outdated
| template<typename V> | ||
| explicit BaseSongFilter(V &&_value) | ||
| :value(std::forward<V>(_value)) {} | ||
| :value(std::forward<V>(_value)), recursive(true) {} |
There was a problem hiding this comment.
Rather than adding an initializer here, it should be on the declaration of the field to specify that this is the default value for all cases where none was given.
But I'm thinking we shouldn't have two constructors; only your new one should exist, and all old callers should be changed to pass the recursive flag (being true for them). When this feature exists, recursiveness should be an explicit decision with no default, because having an implicit default seems more confusing than not.
I'm sorry. May I |
Adds a new filter `directory` similar to `base` but non-recursive. See MusicPlayerDaemon#2418
Adds `directory` filter that is a non-recursive version of BaseSongFilter. This is done by adding a `recursive` flag on BaseSongFilter that the `base` filter sets to `true` and the `directory` filter sets to `false`.
Adds a new filter
directorysimilar tobasebut non-recursive.See #2418
(The commit adds aGetDirectorymethod onLightSongstruct, similar toGetURI. It could be done from within the filter functions, but I think that other (future) features could use this, e.g.group directoryorlist directory.)In its current state (a partial and unoptimized copy of BasSongFilter), it's still very slow!