Optimize queue restore slightly

Reduce the amount of iterations the restoration process has to go through when restoring the queue by making it traverse albums and then album songs.
This commit is contained in:
OxygenCobalt 2020-11-21 11:13:40 -07:00
parent d09ce20e02
commit d2350de12a
2 changed files with 17 additions and 10 deletions

View file

@ -4,6 +4,9 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
/**
* A simplified database entity that represents a given song in the queue.
*/
@Entity(tableName = "queue_table") @Entity(tableName = "queue_table")
data class QueueItem( data class QueueItem(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ -12,6 +15,9 @@ data class QueueItem(
@ColumnInfo(name = "song_id") @ColumnInfo(name = "song_id")
val songId: Long = Long.MIN_VALUE, val songId: Long = Long.MIN_VALUE,
@ColumnInfo(name = "album_id")
val albumId: Long = Long.MIN_VALUE,
@ColumnInfo(name = "is_user_queue") @ColumnInfo(name = "is_user_queue")
val isUserQueue: Boolean = false val isUserQueue: Boolean = false
) )

View file

@ -2,7 +2,6 @@ package org.oxycblt.auxio.playback.state
import android.content.Context import android.content.Context
import android.util.Log import android.util.Log
import kotlin.random.Random
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.oxycblt.auxio.database.AuxioDatabase import org.oxycblt.auxio.database.AuxioDatabase
@ -15,6 +14,7 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import kotlin.random.Random
/** /**
* Master class for the playback state. This should ***not*** be used outside of the playback module. * Master class for the playback state. This should ***not*** be used outside of the playback module.
@ -419,7 +419,7 @@ class PlaybackStateManager private constructor() {
} }
// --- PERSISTENCE FUNCTIONS --- // --- PERSISTENCE FUNCTIONS ---
// TODO: Optimize queue persistence [Storing seed + edits instead of entire queue. // TODO: Implement a fast queue save function that can be enabled in settings
suspend fun saveStateToDatabase(context: Context) { suspend fun saveStateToDatabase(context: Context) {
Log.d(this::class.simpleName, "Saving state to DB.") Log.d(this::class.simpleName, "Saving state to DB.")
@ -462,6 +462,10 @@ class PlaybackStateManager private constructor() {
database.queueDAO.clear() database.queueDAO.clear()
} }
val loadTime = System.currentTimeMillis() - start
Log.d(this::class.simpleName, "Load finished in ${loadTime}ms")
if (states.isEmpty()) { if (states.isEmpty()) {
Log.d(this::class.simpleName, "Nothing here. Not restoring.") Log.d(this::class.simpleName, "Nothing here. Not restoring.")
@ -510,11 +514,11 @@ class PlaybackStateManager private constructor() {
val unified = mutableListOf<QueueItem>() val unified = mutableListOf<QueueItem>()
mUserQueue.forEach { mUserQueue.forEach {
unified.add(QueueItem(songId = it.id, isUserQueue = true)) unified.add(QueueItem(songId = it.id, albumId = it.albumId, isUserQueue = true))
} }
mQueue.forEach { mQueue.forEach {
unified.add(QueueItem(songId = it.id, isUserQueue = false)) unified.add(QueueItem(songId = it.id, albumId = it.albumId, isUserQueue = false))
} }
return unified return unified
@ -542,12 +546,9 @@ class PlaybackStateManager private constructor() {
private fun unpackQueue(queueItems: List<QueueItem>) { private fun unpackQueue(queueItems: List<QueueItem>) {
val musicStore = MusicStore.getInstance() val musicStore = MusicStore.getInstance()
Log.d(this::class.simpleName, queueItems.size.toString()) queueItems.forEach { item ->
// Traverse albums and then album songs instead of just the songs, as its faster.
for (item in queueItems) { musicStore.albums.find { it.id == item.albumId }?.songs?.find { it.id == item.songId }?.let {
musicStore.songs.find { it.id == item.songId }?.let {
Log.d(this::class.simpleName, it.id.toString())
if (item.isUserQueue) { if (item.isUserQueue) {
mUserQueue.add(it) mUserQueue.add(it)
} else { } else {