Skip to content

Commit

Permalink
perf: improve search speed by 10x-30x~, #61
Browse files Browse the repository at this point in the history
  • Loading branch information
MSOB7YY committed Nov 13, 2023
1 parent 0f5670c commit 8395cde
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 59 deletions.
122 changes: 63 additions & 59 deletions lib/controller/search_sort_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ class SearchSortController {

void searchAll(String text) {
lastSearchText = text;
final enabledSearches = settings.activeSearchMediaTypes;

_searchTracks(text, temp: true);
_searchMediaType(type: MediaType.album, text: text, temp: true);
_searchMediaType(type: MediaType.artist, text: text, temp: true);
_searchMediaType(type: MediaType.genre, text: text, temp: true);
_searchPlaylists(text, temp: true);
_searchMediaType(type: MediaType.folder, text: text, temp: true);
if (enabledSearches.contains(MediaType.album)) _searchMediaType(type: MediaType.album, text: text, temp: true);
if (enabledSearches.contains(MediaType.artist)) _searchMediaType(type: MediaType.artist, text: text, temp: true);
if (enabledSearches.contains(MediaType.genre)) _searchMediaType(type: MediaType.genre, text: text, temp: true);
if (enabledSearches.contains(MediaType.playlist)) _searchPlaylists(text, temp: true);
if (enabledSearches.contains(MediaType.folder)) _searchMediaType(type: MediaType.folder, text: text, temp: true);
}

void searchMedia(String text, MediaType? media) {
Expand Down Expand Up @@ -142,35 +144,40 @@ class SearchSortController {
final tsf = settings.trackSearchFilter;
final cleanup = settings.enableSearchCleanup.value;

final map = Indexer.inst.allTracksMappedByPath.map((key, value) {
final artistsList = Indexer.splitArtist(
title: value.title,
originalArtist: value.originalArtist,
config: ArtistsSplitConfig.settings(),
);
final genresList = Indexer.splitGenre(
value.originalGenre,
config: GenresSplitConfig.settings(),
);
final valueMap = value.toJson();
valueMap['artistsList'] = artistsList;
valueMap['genresList'] = genresList;
return MapEntry(key, valueMap);
}); // ~0.000010 second

final result = await _searchTracksIsolate.thready({
'tsf': tsf.toList(),
'cleanup': cleanup,
'tracks': map,
'text': text,
final function = _functionOfCleanup(cleanup);
String textCleanedForSearch(String textToClean) => function(textToClean);

final stitle = tsf.contains(TrackSearchFilter.title);
final sfilename = tsf.contains(TrackSearchFilter.filename);
final salbum = tsf.contains(TrackSearchFilter.album);
final salbumartist = tsf.contains(TrackSearchFilter.albumartist);
final sartist = tsf.contains(TrackSearchFilter.artist);
final sgenre = tsf.contains(TrackSearchFilter.genre);
final scomposer = tsf.contains(TrackSearchFilter.composer);
final syear = tsf.contains(TrackSearchFilter.year);

final result = <Track>[];
Indexer.inst.tracksInfoList.loop((tr, index) {
final trExt = tr.toTrackExt();
final lctext = textCleanedForSearch(text);

if ((stitle && textCleanedForSearch(trExt.title).contains(lctext)) ||
(sfilename && textCleanedForSearch((trExt.path).getFilename).contains(lctext)) ||
(salbum && textCleanedForSearch(trExt.album).contains(lctext)) ||
(salbumartist && textCleanedForSearch(trExt.albumArtist).contains(lctext)) ||
(sartist && (trExt.artistsList).any((element) => textCleanedForSearch(element).contains(lctext))) ||
(sgenre && (trExt.genresList).any((element) => textCleanedForSearch(element).contains(lctext))) ||
(scomposer && textCleanedForSearch(trExt.composer).contains(lctext)) ||
(syear && textCleanedForSearch((trExt.year).toString()).contains(lctext))) {
result.add(tr);
}
});

final finalList = temp ? trackSearchTemp : trackSearchList;

finalList
..clear()
..addAll(result);

printy("Search Tracks Found: ${finalList.length}");
}

void _searchMediaType({required MediaType type, required String text, bool temp = false}) async {
Expand Down Expand Up @@ -595,42 +602,39 @@ class SearchSortController {
_searchPlaylists(LibraryTab.playlists.textSearchController?.text ?? '');
}

static List<Track> _searchTracksIsolate(Map parameters) {
final tsf = parameters['tsf'] as List<TrackSearchFilter>;
final cleanup = parameters['cleanup'] as bool;
final tracks = parameters['tracks'] as Map<Track, Map<String, dynamic>>;
final text = parameters['text'] as String;

final function = _functionOfCleanup(cleanup);
String textCleanedForSearch(String textToClean) => function(textToClean);

bool hasF(TrackSearchFilter f) => tsf.contains(f);
// static List<Track> _searchTracksIsolate(Map parameters) {
// final tsf = parameters['tsf'] as List<TrackSearchFilter>;
// final cleanup = parameters['cleanup'] as bool;
// final tracks = parameters['tracks'] as Map<Track, Map<String, dynamic>>;
// final text = parameters['text'] as String;

final finalList = <Track>[];
// final function = _functionOfCleanup(cleanup);
// String textCleanedForSearch(String textToClean) => function(textToClean);

// -- well i dont think we need the overhead of converting the map into a TrackExtended Object.
// -- we'll just access the map values.
for (final entry in tracks.entries) {
final trExt = entry.value;
final lctext = textCleanedForSearch(text);
// bool hasF(TrackSearchFilter f) => tsf.contains(f);

if ((hasF(TrackSearchFilter.title) && textCleanedForSearch(trExt['title'] as String).contains(lctext)) ||
(hasF(TrackSearchFilter.filename) && textCleanedForSearch((trExt['path'] as String).getFilename).contains(lctext)) ||
(hasF(TrackSearchFilter.album) && textCleanedForSearch(trExt['album'] as String).contains(lctext)) ||
(hasF(TrackSearchFilter.albumartist) && textCleanedForSearch(trExt['albumArtist'] as String).contains(lctext)) ||
(hasF(TrackSearchFilter.artist) && (trExt['artistsList'] as List<String>).any((element) => textCleanedForSearch(element).contains(lctext))) ||
(hasF(TrackSearchFilter.genre) && (trExt['genresList'] as List<String>).any((element) => textCleanedForSearch(element).contains(lctext))) ||
(hasF(TrackSearchFilter.composer) && textCleanedForSearch(trExt['composer'] as String).contains(lctext)) ||
(hasF(TrackSearchFilter.year) && textCleanedForSearch((trExt['year'] as int).toString()).contains(lctext))) {
finalList.add(entry.key);
}
}
// final finalList = <Track>[];

// tracks.loop((tr, index) {
// // -- well i dont think we need the overhead of converting the map into a TrackExtended Object.
// // -- we'll just access the map values.
// for (final entry in tracks.entries) {
// final trExt = entry.value;
// final lctext = textCleanedForSearch(text);

// });
return finalList;
}
// if ((hasF(TrackSearchFilter.title) && textCleanedForSearch(trExt['title'] as String).contains(lctext)) ||
// (hasF(TrackSearchFilter.filename) && textCleanedForSearch((trExt['path'] as String).getFilename).contains(lctext)) ||
// (hasF(TrackSearchFilter.album) && textCleanedForSearch(trExt['album'] as String).contains(lctext)) ||
// (hasF(TrackSearchFilter.albumartist) && textCleanedForSearch(trExt['albumArtist'] as String).contains(lctext)) ||
// (hasF(TrackSearchFilter.artist) && (trExt['artistsList'] as List<String>).any((element) => textCleanedForSearch(element).contains(lctext))) ||
// (hasF(TrackSearchFilter.genre) && (trExt['genresList'] as List<String>).any((element) => textCleanedForSearch(element).contains(lctext))) ||
// (hasF(TrackSearchFilter.composer) && textCleanedForSearch(trExt['composer'] as String).contains(lctext)) ||
// (hasF(TrackSearchFilter.year) && textCleanedForSearch((trExt['year'] as int).toString()).contains(lctext))) {
// finalList.add(entry.key);
// }
// }

// return finalList;
// }

// static Iterable<MapEntry<String, Playlist>> _searchPlaylistsIsolate(Map parameters) {
// final psf = parameters['psf'] as List<String>;
Expand Down
1 change: 1 addition & 0 deletions lib/ui/pages/search_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class SearchPage extends StatelessWidget {
settings.removeFromList(activeSearchMediaTypes1: e);
} else {
settings.save(activeSearchMediaTypes: [e]);
SearchSortController.inst.searchAll(ScrollSearchController.inst.searchTextEditingController.text);
}
},
margin: const EdgeInsets.symmetric(horizontal: 3.0, vertical: 12.0),
Expand Down

0 comments on commit 8395cde

Please sign in to comment.