music: cache ids in map
Make a map of ids to particular music items, which makes searching for music items much faster at the cost of higher memory usage.
This commit is contained in:
parent
b2085e440e
commit
8a15868ba1
3 changed files with 37 additions and 32 deletions
|
@ -114,7 +114,7 @@ class DetailViewModel(application: Application) :
|
|||
fun setSongId(id: Long) {
|
||||
if (_currentSong.value?.run { song.id } == id) return
|
||||
val library = unlikelyToBeNull(musicStore.library)
|
||||
val song = requireNotNull(library.songs.find { it.id == id }) { "Invalid song id provided" }
|
||||
val song = requireNotNull(library.findSongById(id)) { "Invalid song id provided" }
|
||||
generateDetailSong(song)
|
||||
}
|
||||
|
||||
|
@ -126,8 +126,7 @@ class DetailViewModel(application: Application) :
|
|||
fun setAlbumId(id: Long) {
|
||||
if (_currentAlbum.value?.id == id) return
|
||||
val library = unlikelyToBeNull(musicStore.library)
|
||||
val album =
|
||||
requireNotNull(library.albums.find { it.id == id }) { "Invalid album id provided " }
|
||||
val album = requireNotNull(library.findAlbumById(id)) { "Invalid album id provided " }
|
||||
|
||||
_currentAlbum.value = album
|
||||
refreshAlbumData(album)
|
||||
|
@ -136,8 +135,7 @@ class DetailViewModel(application: Application) :
|
|||
fun setArtistId(id: Long) {
|
||||
if (_currentArtist.value?.id == id) return
|
||||
val library = unlikelyToBeNull(musicStore.library)
|
||||
val artist =
|
||||
requireNotNull(library.artists.find { it.id == id }) { "Invalid artist id provided" }
|
||||
val artist = requireNotNull(library.findArtistById(id)) { "Invalid artist id provided" }
|
||||
_currentArtist.value = artist
|
||||
refreshArtistData(artist)
|
||||
}
|
||||
|
@ -145,8 +143,7 @@ class DetailViewModel(application: Application) :
|
|||
fun setGenreId(id: Long) {
|
||||
if (_currentGenre.value?.id == id) return
|
||||
val library = unlikelyToBeNull(musicStore.library)
|
||||
val genre =
|
||||
requireNotNull(library.genres.find { it.id == id }) { "Invalid genre id provided" }
|
||||
val genre = requireNotNull(library.findGenreById(id)) { "Invalid genre id provided" }
|
||||
_currentGenre.value = genre
|
||||
refreshGenreData(genre)
|
||||
}
|
||||
|
|
|
@ -75,12 +75,37 @@ class MusicStore private constructor() {
|
|||
val albums: List<Album>,
|
||||
val songs: List<Song>
|
||||
) {
|
||||
/** Find a song in a faster manner by using the album ID as well.. */
|
||||
fun findSongFast(songId: Long, albumId: Long) =
|
||||
albums.find { it.id == albumId }.run { songs.find { it.id == songId } }
|
||||
private val genreIdMap = HashMap<Long, Genre>().apply { genres.forEach { put(it.id, it) } }
|
||||
private val artistIdMap =
|
||||
HashMap<Long, Artist>().apply { artists.forEach { put(it.id, it) } }
|
||||
private val albumIdMap = HashMap<Long, Album>().apply { albums.forEach { put(it.id, it) } }
|
||||
private val songIdMap = HashMap<Long, Song>().apply { songs.forEach { put(it.id, it) } }
|
||||
|
||||
/** Find a [Song] by it's ID. Null if no song exists with that ID. */
|
||||
fun findSongById(songId: Long) = songIdMap[songId]
|
||||
|
||||
/** Find a [Album] by it's ID. Null if no album exists with that ID. */
|
||||
fun findAlbumById(albumId: Long) = albumIdMap[albumId]
|
||||
|
||||
/** Find a [Artist] by it's ID. Null if no artist exists with that ID. */
|
||||
fun findArtistById(artistId: Long) = artistIdMap[artistId]
|
||||
|
||||
/** Find a [Genre] by it's ID. Null if no genre exists with that ID. */
|
||||
fun findGenreById(genreId: Long) = genreIdMap[genreId]
|
||||
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(song: Song) = findSongById(song.id)
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(songs: List<Song>) = songs.mapNotNull { sanitize(it) }
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(album: Album) = findAlbumById(album.id)
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(artist: Artist) = findArtistById(artist.id)
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(genre: Genre) = findGenreById(genre.id)
|
||||
|
||||
/**
|
||||
* Find a song for a [uri], this is similar to [findSongFast], but with some kind of content
|
||||
* Find a song for a [uri], this is similar to [findSong], but with some kind of content
|
||||
* uri.
|
||||
* @return The corresponding [Song] for this [uri], null if there isn't one.
|
||||
*/
|
||||
|
@ -94,17 +119,6 @@ class MusicStore private constructor() {
|
|||
|
||||
songs.find { it.path.name == displayName }
|
||||
}
|
||||
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(song: Song) = songs.find { it.id == song.id }
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(songs: List<Song>) = songs.mapNotNull { sanitize(it) }
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(album: Album) = albums.find { it.id == album.id }
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(artist: Artist) = artists.find { it.id == artist.id }
|
||||
/** Sanitize an old item to find the corresponding item in a new library. */
|
||||
fun sanitize(genre: Genre) = genres.find { it.id == genre.id }
|
||||
}
|
||||
|
||||
/** A callback for awaiting the loading of music. */
|
||||
|
|
|
@ -116,9 +116,9 @@ class PlaybackStateDatabase private constructor(context: Context) :
|
|||
val parent =
|
||||
when (rawState.playbackMode) {
|
||||
PlaybackMode.ALL_SONGS -> null
|
||||
PlaybackMode.IN_ALBUM -> library.albums.find { it.id == rawState.parentId }
|
||||
PlaybackMode.IN_ARTIST -> library.artists.find { it.id == rawState.parentId }
|
||||
PlaybackMode.IN_GENRE -> library.genres.find { it.id == rawState.parentId }
|
||||
PlaybackMode.IN_ALBUM -> rawState.parentId?.let(library::findAlbumById)
|
||||
PlaybackMode.IN_ARTIST -> rawState.parentId?.let(library::findArtistById)
|
||||
PlaybackMode.IN_GENRE -> rawState.parentId?.let(library::findGenreById)
|
||||
}
|
||||
|
||||
return SavedState(
|
||||
|
@ -168,15 +168,9 @@ class PlaybackStateDatabase private constructor(context: Context) :
|
|||
|
||||
readableDatabase.queryAll(TABLE_NAME_QUEUE) { cursor ->
|
||||
if (cursor.count == 0) return@queryAll
|
||||
|
||||
val songIndex = cursor.getColumnIndexOrThrow(QueueColumns.SONG_ID)
|
||||
val albumIndex = cursor.getColumnIndexOrThrow(QueueColumns.ALBUM_ID)
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
library.findSongFast(cursor.getLong(songIndex), cursor.getLong(albumIndex))?.let {
|
||||
song ->
|
||||
queue.add(song)
|
||||
}
|
||||
library.findSongById(cursor.getLong(songIndex))?.let(queue::add)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue