music: simplify tag extraction spin
Simplify the tag extraction loop to not depend on the co-routine primitives. This actually makes the music loading process a bit faster since the loop isn't as tight.
This commit is contained in:
parent
213409924b
commit
d0b2fb8517
3 changed files with 20 additions and 16 deletions
|
@ -47,6 +47,7 @@ class Auxio : Application() {
|
|||
// Adding static shortcuts in a dynamic manner is better than declaring them
|
||||
// manually, as it will properly handle the difference between debug and release
|
||||
// Auxio instances.
|
||||
// TODO: Switch to static shortcuts
|
||||
ShortcutManagerCompat.addDynamicShortcuts(
|
||||
this,
|
||||
listOf(
|
||||
|
|
|
@ -57,25 +57,22 @@ class TagExtractorImpl @Inject constructor(@ApplicationContext private val conte
|
|||
// producing similar throughput's to other kinds of manual metadata extraction.
|
||||
val taskPool: Array<Task?> = arrayOfNulls(TASK_CAPACITY)
|
||||
|
||||
spin@ while (true) {
|
||||
// Spin until there is an open slot we can insert a task in.
|
||||
for (i in taskPool.indices) {
|
||||
val task = taskPool[i]
|
||||
if (task != null) {
|
||||
val finishedRawSong = task.get()
|
||||
if (finishedRawSong != null) {
|
||||
completeSongs.send(finishedRawSong)
|
||||
yield()
|
||||
} else {
|
||||
continue
|
||||
for (song in incompleteSongs) {
|
||||
spin@ while (true) {
|
||||
for (i in taskPool.indices) {
|
||||
val task = taskPool[i]
|
||||
if (task != null) {
|
||||
val finishedRawSong = task.get()
|
||||
if (finishedRawSong != null) {
|
||||
completeSongs.send(finishedRawSong)
|
||||
yield()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
val result = incompleteSongs.tryReceive()
|
||||
if (result.isClosed) {
|
||||
taskPool[i] = null
|
||||
taskPool[i] = Task(context, song)
|
||||
break@spin
|
||||
}
|
||||
taskPool[i] = result.getOrNull()?.let { Task(context, it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -328,6 +328,7 @@ constructor(
|
|||
): Library {
|
||||
if (ContextCompat.checkSelfPermission(context, Indexer.PERMISSION_READ_AUDIO) ==
|
||||
PackageManager.PERMISSION_DENIED) {
|
||||
logE("Permission check failed")
|
||||
// No permissions, signal that we can't do anything.
|
||||
throw Indexer.NoPermissionException()
|
||||
}
|
||||
|
@ -337,6 +338,7 @@ constructor(
|
|||
emitIndexing(Indexer.Indexing.Indeterminate)
|
||||
|
||||
// Do the initial query of the cache and media databases in parallel.
|
||||
logD("Starting queries")
|
||||
val mediaStoreQueryJob = scope.async { mediaStoreExtractor.query() }
|
||||
val cache =
|
||||
if (withCache) {
|
||||
|
@ -349,6 +351,7 @@ constructor(
|
|||
// Now start processing the queried song information in parallel. Songs that can't be
|
||||
// received from the cache are consisted incomplete and pushed to a separate channel
|
||||
// that will eventually be processed into completed raw songs.
|
||||
logD("Starting song discovery")
|
||||
val completeSongs = Channel<RawSong>(Channel.UNLIMITED)
|
||||
val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED)
|
||||
val mediaStoreJob =
|
||||
|
@ -363,15 +366,18 @@ constructor(
|
|||
rawSongs.add(rawSong)
|
||||
emitIndexing(Indexer.Indexing.Songs(rawSongs.size, query.projectedTotal))
|
||||
}
|
||||
// These should be no-ops
|
||||
mediaStoreJob.await()
|
||||
metadataJob.await()
|
||||
|
||||
if (rawSongs.isEmpty()) {
|
||||
logE("Music library was empty")
|
||||
throw Indexer.NoMusicException()
|
||||
}
|
||||
|
||||
// Successfully loaded the library, now save the cache and create the library in
|
||||
// parallel.
|
||||
logD("Discovered ${rawSongs.size} songs, starting finalization")
|
||||
emitIndexing(Indexer.Indexing.Indeterminate)
|
||||
val libraryJob = scope.async(Dispatchers.Main) { Library.from(rawSongs, musicSettings) }
|
||||
if (cache == null || cache.invalidated) {
|
||||
|
|
Loading…
Reference in a new issue