-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Analyze and improve search in File Browser (again) #6985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 26 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
5e215cd
Remove inHiddenDirectory
sakertooth 602213f
Redesign searcher class
sakertooth f21e2dd
Search filesystem using BFS and batching
sakertooth accc299
Fix bugs
sakertooth 86bf619
Tweak batch tunables
sakertooth 9f92f88
Implement buildSearchTree (wip)
sakertooth 86aff46
Use fileName instead of baseName
sakertooth 33bb51d
Fix issues that caused most entries to be missed
sakertooth 54e0e15
Do not make changes to original m_filter
sakertooth fbca473
Do not update unmatched parent directories
sakertooth e353b0a
Redesign FileBrowserSearcher to use futures
sakertooth 1f62974
Add search indicator using a progress bar
sakertooth 85a5ce0
Update view with 256 items after 250 milliseconds
sakertooth d1a28f4
Deactivate signal under worker lock
sakertooth ba66e25
Remove QUuid include
sakertooth aca79b1
Remove filterAndExpandItems
sakertooth 5cfb4d6
Abort building search tree when cancelled
sakertooth fe95fa9
Add border radius for progress chunks
sakertooth d2513c4
Undo formatting changes
sakertooth 634d1c7
Replace updateOnExpand with updatePixmaps
sakertooth 7153b92
Tweak batch size and time interval again
sakertooth 092f7bd
Fix issue with directory population
sakertooth 1c06d24
Sort entries when doing BFS search
sakertooth d00a461
Only expand parent folders
sakertooth cc7aab0
Support filtering of user and factory content when searching
sakertooth 58d2e1f
Do not run a search without any directories
sakertooth 2db8c4f
Fix naming style of constants
sakertooth 714291e
Undo progress bar styling
sakertooth 1156829
Simplify processing of batches
sakertooth 031770b
Tweak batch size and interval to 64 and 250
sakertooth efeb240
Add directory blacklist
sakertooth 3d55993
Do not use braces
sakertooth 63543d4
Do not use iterators in pushInBatches
sakertooth b5ddc4e
Use DFS properly within process function
sakertooth 2b51e2a
Add single item every millisecond
sakertooth 79a2e0e
Add documentation
sakertooth File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| /* | ||
| * FileBrowserSearcher.h - Batch processor for searching the filesystem | ||
| * | ||
| * Copyright (c) 2023 saker <[email protected]> | ||
| * | ||
| * This file is part of LMMS - https://lmms.io | ||
| * | ||
| * This program is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU General Public | ||
| * License as published by the Free Software Foundation; either | ||
| * version 2 of the License, or (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public | ||
| * License along with this program (see COPYING); if not, write to the | ||
| * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
| * Boston, MA 02110-1301 USA. | ||
| * | ||
| */ | ||
|
|
||
| #ifndef LMMS_FILE_BROWSER_SEARCHER_H | ||
| #define LMMS_FILE_BROWSER_SEARCHER_H | ||
|
|
||
| #include <QHash> | ||
| #include <QString> | ||
| #include <QStringList> | ||
| #include <optional> | ||
| #include <queue> | ||
|
|
||
| #ifdef __MINGW32__ | ||
| #include <mingw.condition_variable.h> | ||
| #include <mingw.mutex.h> | ||
| #include <mingw.thread.h> | ||
| #else | ||
| #include <condition_variable> | ||
| #include <mutex> | ||
| #include <thread> | ||
| #endif | ||
|
|
||
| namespace lmms::gui { | ||
| class FileBrowserSearcher | ||
| { | ||
| public: | ||
| static constexpr int s_batchSize = 16; | ||
| static constexpr int s_millisecondsPerBatch = 500; | ||
|
|
||
| //! The future that will be returned to the requester, as well as read and modified by both the requester and | ||
| //! worker thread. Acessing the filter, paths to search, and valid file extensions can be done concurrently since | ||
| //! they do not change after construction. Access to the batch queue is protected under a mutex, while the state | ||
| //! variable is atomic. | ||
| class SearchFuture | ||
| { | ||
| public: | ||
| //! The state for this future. The state of this object can be read/written atomically. In a cancelled | ||
| //! state, the requester doesn't need to continue using this future and can abort any operations made using it. | ||
| //! Once in a completed or cancelled state, the worker thread no longer has shared ownership of this future | ||
| //! (i.e., all ownership will go to the requester). | ||
| enum class State | ||
| { | ||
| Idle, | ||
| Running, | ||
| Cancelled, | ||
| Completed | ||
| }; | ||
|
|
||
| SearchFuture(const QString& filter, const QStringList& paths, const QStringList& extensions) | ||
| : m_filter(filter) | ||
| , m_paths(paths) | ||
| , m_extensions(extensions) | ||
| { | ||
| } | ||
|
|
||
| //! Read the current state of the future object. This function can run concurrently with the worker thread. | ||
| auto state() -> State { return m_state; } | ||
|
|
||
| //! Read a batch of search results. This function can run concurrently with the worker thread. Returns a empty | ||
| //! list if no batches are available. | ||
| auto batch() -> QStringList; | ||
|
|
||
| auto filter() -> const QString& { return m_filter; } | ||
| auto paths() -> const QStringList& { return m_paths; } | ||
| auto extensions() -> const QStringList& { return m_extensions; } | ||
|
|
||
| private: | ||
| auto addBatch(QStringList& matches) -> void; | ||
|
|
||
| QString m_filter; | ||
| QStringList m_paths; | ||
| QStringList m_extensions; | ||
|
|
||
| std::list<QStringList> m_batchQueue; | ||
| std::mutex m_batchQueueMutex; | ||
|
|
||
| std::atomic<State> m_state = State::Idle; | ||
|
|
||
| friend FileBrowserSearcher; | ||
| }; | ||
|
|
||
| ~FileBrowserSearcher(); | ||
|
|
||
| //! Enqueues a search to be ran by the worker thread. | ||
| //! Returns a future that the caller can use to track state and results of the operation. | ||
| auto search(const QString& filter, const QStringList& paths, const QStringList& extensions) | ||
| -> std::shared_ptr<SearchFuture>; | ||
|
|
||
| //! Sends a signal to cancel a running search. | ||
| auto cancel() -> void { m_cancelRunningSearch = true; } | ||
|
|
||
| //! Returns the global instance of the searcher object. | ||
| static auto instance() -> FileBrowserSearcher* | ||
| { | ||
| static auto s_instance = FileBrowserSearcher{}; | ||
| return &s_instance; | ||
| } | ||
|
|
||
| private: | ||
| auto run() -> void; | ||
| auto process(std::shared_ptr<SearchFuture> searchFuture) -> void; | ||
|
|
||
| std::queue<std::shared_ptr<SearchFuture>> m_searchQueue; | ||
| std::atomic<bool> m_cancelRunningSearch = false; | ||
|
|
||
| bool m_workerStopped = false; | ||
| std::mutex m_workerMutex; | ||
| std::condition_variable m_workerCond; | ||
| std::thread m_worker{[this] { run(); }}; | ||
| }; | ||
| } // namespace lmms::gui | ||
|
|
||
| #endif // LMMS_FILE_BROWSER_SEARCHER_H | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.