all: do not do work on static initialization
Try to lazily initialize certain static variables that do work (like Regex) to speed up initialization time.
This commit is contained in:
parent
c98ca8712f
commit
a5176d6209
9 changed files with 30 additions and 34 deletions
|
@ -568,8 +568,8 @@ private inline fun <T : Music, K> compareByDynamic(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to create a [Comparator] that sorts in ascending order based on the
|
* Utility function to create a [Comparator] that sorts in ascending order based on the given
|
||||||
* given [Comparator], with a selector based on the item itself.
|
* [Comparator], with a selector based on the item itself.
|
||||||
*
|
*
|
||||||
* @param comparator The [Comparator] to wrap.
|
* @param comparator The [Comparator] to wrap.
|
||||||
* @return A new [Comparator] with the specified configuration.
|
* @return A new [Comparator] with the specified configuration.
|
||||||
|
@ -581,8 +581,8 @@ private fun <T : Music> compareBy(comparator: Comparator<T>): Comparator<T> =
|
||||||
/**
|
/**
|
||||||
* A [Comparator] that chains several other [Comparator]s together to form one comparison.
|
* A [Comparator] that chains several other [Comparator]s together to form one comparison.
|
||||||
*
|
*
|
||||||
* @param comparators The [Comparator]s to chain. These will be iterated through in order
|
* @param comparators The [Comparator]s to chain. These will be iterated through in order during a
|
||||||
* during a comparison, with the first non-equal result becoming the result.
|
* comparison, with the first non-equal result becoming the result.
|
||||||
*/
|
*/
|
||||||
private class MultiComparator<T>(vararg comparators: Comparator<T>) : Comparator<T> {
|
private class MultiComparator<T>(vararg comparators: Comparator<T>) : Comparator<T> {
|
||||||
private val _comparators = comparators
|
private val _comparators = comparators
|
||||||
|
@ -656,8 +656,8 @@ private class BasicComparator<T : Music> private constructor() : Comparator<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [Comparator] that compares two possibly null values. Values will be considered lesser
|
* A [Comparator] that compares two possibly null values. Values will be considered lesser if they
|
||||||
* if they are null, and greater if they are non-null.
|
* are null, and greater if they are non-null.
|
||||||
*/
|
*/
|
||||||
private class NullableComparator<T : Comparable<T>> private constructor() : Comparator<T?> {
|
private class NullableComparator<T : Comparable<T>> private constructor() : Comparator<T?> {
|
||||||
override fun compare(a: T?, b: T?) =
|
override fun compare(a: T?, b: T?) =
|
||||||
|
|
|
@ -23,6 +23,8 @@ import android.content.pm.PackageManager
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
|
@ -32,12 +34,9 @@ import org.oxycblt.auxio.music.device.RawSong
|
||||||
import org.oxycblt.auxio.music.fs.MediaStoreExtractor
|
import org.oxycblt.auxio.music.fs.MediaStoreExtractor
|
||||||
import org.oxycblt.auxio.music.metadata.TagExtractor
|
import org.oxycblt.auxio.music.metadata.TagExtractor
|
||||||
import org.oxycblt.auxio.music.user.UserLibrary
|
import org.oxycblt.auxio.music.user.UserLibrary
|
||||||
import org.oxycblt.auxio.util.fallible
|
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logE
|
import org.oxycblt.auxio.util.logE
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logW
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.coroutines.EmptyCoroutineContext
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primary manager of music information and loading.
|
* Primary manager of music information and loading.
|
||||||
|
@ -293,7 +292,7 @@ constructor(
|
||||||
val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED)
|
val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED)
|
||||||
val mediaStoreJob =
|
val mediaStoreJob =
|
||||||
worker.scope.tryAsync {
|
worker.scope.tryAsync {
|
||||||
mediaStoreExtractor.consume(query, cache, incompleteSongs, completeSongs) }.also {
|
mediaStoreExtractor.consume(query, cache, incompleteSongs, completeSongs)
|
||||||
incompleteSongs.close()
|
incompleteSongs.close()
|
||||||
}
|
}
|
||||||
val metadataJob =
|
val metadataJob =
|
||||||
|
@ -326,7 +325,10 @@ constructor(
|
||||||
worker.scope.tryAsync(Dispatchers.Main) {
|
worker.scope.tryAsync(Dispatchers.Main) {
|
||||||
deviceLibraryFactory.create(rawSongs).also { deviceLibraryChannel.send(it) }
|
deviceLibraryFactory.create(rawSongs).also { deviceLibraryChannel.send(it) }
|
||||||
}
|
}
|
||||||
val userLibraryJob = worker.scope.tryAsync { userLibraryFactory.read(deviceLibraryChannel) }
|
val userLibraryJob =
|
||||||
|
worker.scope.tryAsync {
|
||||||
|
userLibraryFactory.read(deviceLibraryChannel).also { deviceLibraryChannel.close() }
|
||||||
|
}
|
||||||
if (cache == null || cache.invalidated) {
|
if (cache == null || cache.invalidated) {
|
||||||
cacheRepository.writeCache(rawSongs)
|
cacheRepository.writeCache(rawSongs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,9 +185,10 @@ class Date private constructor(private val tokens: List<Int>) : Comparable<Date>
|
||||||
* A [Regex] that can parse a variable-precision ISO-8601 timestamp. Derived from
|
* A [Regex] that can parse a variable-precision ISO-8601 timestamp. Derived from
|
||||||
* https://github.com/quodlibet/mutagen
|
* https://github.com/quodlibet/mutagen
|
||||||
*/
|
*/
|
||||||
private val ISO8601_REGEX =
|
private val ISO8601_REGEX by lazy {
|
||||||
Regex(
|
Regex(
|
||||||
"""^(\d{4})([-.](\d{2})([-.](\d{2})([T ](\d{2})([:.](\d{2})([:.](\d{2})(Z)?)?)?)?)?)?$""")
|
"""^(\d{4})([-.](\d{2})([-.](\d{2})([T ](\d{2})([:.](\d{2})([:.](\d{2})(Z)?)?)?)?)?)?$""")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a [Date] from a year component.
|
* Create a [Date] from a year component.
|
||||||
|
|
|
@ -35,7 +35,7 @@ sealed interface Name : Comparable<Name> {
|
||||||
/**
|
/**
|
||||||
* A logical first character that can be used to collate a sorted list of music.
|
* A logical first character that can be used to collate a sorted list of music.
|
||||||
*
|
*
|
||||||
* TODO: Move this to the home view
|
* TODO: Move this to the home package
|
||||||
*/
|
*/
|
||||||
val thumb: String
|
val thumb: String
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ sealed interface Name : Comparable<Name> {
|
||||||
|
|
||||||
final override val thumb: String
|
final override val thumb: String
|
||||||
get() =
|
get() =
|
||||||
// TODO: Remove these checks once you have real unit testing
|
// TODO: Remove these safety checks once you have real unit testing
|
||||||
sortTokens
|
sortTokens
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
?.run { collationKey.sourceString.firstOrNull() }
|
?.run { collationKey.sourceString.firstOrNull() }
|
||||||
|
@ -114,8 +114,7 @@ sealed interface Name : Comparable<Name> {
|
||||||
*
|
*
|
||||||
* @param raw The raw name obtained from the music item
|
* @param raw The raw name obtained from the music item
|
||||||
* @param sort The raw sort name obtained from the music item
|
* @param sort The raw sort name obtained from the music item
|
||||||
* @param musicSettings [MusicSettings] required to obtain user-preferred sorting
|
* @param musicSettings [MusicSettings] required for name configuration.
|
||||||
* configurations
|
|
||||||
*/
|
*/
|
||||||
fun from(raw: String, sort: String?, musicSettings: MusicSettings): Known =
|
fun from(raw: String, sort: String?, musicSettings: MusicSettings): Known =
|
||||||
if (musicSettings.intelligentSorting) {
|
if (musicSettings.intelligentSorting) {
|
||||||
|
@ -145,7 +144,7 @@ sealed interface Name : Comparable<Name> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val COLLATOR: Collator = Collator.getInstance().apply { strength = Collator.PRIMARY }
|
private val COLLATOR: Collator = Collator.getInstance().apply { strength = Collator.PRIMARY }
|
||||||
private val PUNCT_REGEX = Regex("[\\p{Punct}+]")
|
private val PUNCT_REGEX by lazy { Regex("[\\p{Punct}+]") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plain [Name.Known] implementation that is internationalization-safe.
|
* Plain [Name.Known] implementation that is internationalization-safe.
|
||||||
|
@ -215,6 +214,6 @@ private data class IntelligentKnownName(override val raw: String, override val s
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TOKEN_REGEX = Regex("(\\d+)|(\\D+)")
|
private val TOKEN_REGEX by lazy { Regex("(\\d+)|(\\D+)") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ private fun String.parseId3v1Genre(): String? {
|
||||||
* A [Regex] that implements parsing for ID3v2's genre format. Derived from mutagen:
|
* A [Regex] that implements parsing for ID3v2's genre format. Derived from mutagen:
|
||||||
* https://github.com/quodlibet/mutagen
|
* https://github.com/quodlibet/mutagen
|
||||||
*/
|
*/
|
||||||
private val ID3V2_GENRE_RE = Regex("((?:\\((\\d+|RX|CR)\\))*)(.+)?")
|
private val ID3V2_GENRE_RE by lazy { Regex("((?:\\((\\d+|RX|CR)\\))*)(.+)?") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an ID3v2 integer genre field, which has support for multiple genre values and combined
|
* Parse an ID3v2 integer genre field, which has support for multiple genre values and combined
|
||||||
|
|
|
@ -47,6 +47,11 @@ private constructor(
|
||||||
*/
|
*/
|
||||||
inline fun edit(edits: MutableList<Song>.() -> Unit) = edit(songs.toMutableList().apply(edits))
|
inline fun edit(edits: MutableList<Song>.() -> Unit) = edit(songs.toMutableList().apply(edits))
|
||||||
|
|
||||||
|
override fun equals(other: Any?) =
|
||||||
|
other is PlaylistImpl && uid == other.uid && songs == other.songs
|
||||||
|
|
||||||
|
override fun hashCode() = 31 * uid.hashCode() + songs.hashCode()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Create a new instance with a novel UID.
|
* Create a new instance with a novel UID.
|
||||||
|
|
|
@ -294,6 +294,6 @@ constructor(
|
||||||
* Matches non-float information from ReplayGain adjustments. Derived from vanilla music:
|
* Matches non-float information from ReplayGain adjustments. Derived from vanilla music:
|
||||||
* https://github.com/vanilla-music/vanilla
|
* https://github.com/vanilla-music/vanilla
|
||||||
*/
|
*/
|
||||||
val REPLAYGAIN_ADJUSTMENT_FILTER_REGEX = Regex("[^\\d.-]")
|
val REPLAYGAIN_ADJUSTMENT_FILTER_REGEX by lazy { Regex("[^\\d.-]") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,8 @@ class SearchEngineImpl @Inject constructor(@ApplicationContext private val conte
|
||||||
* Converts the output of [Normalizer] to remove any junk characters added by it's
|
* Converts the output of [Normalizer] to remove any junk characters added by it's
|
||||||
* replacements, alongside punctuation.
|
* replacements, alongside punctuation.
|
||||||
*/
|
*/
|
||||||
val NORMALIZE_POST_PROCESSING_REGEX =
|
val NORMALIZE_POST_PROCESSING_REGEX by lazy {
|
||||||
Regex("(\\p{InCombiningDiacriticalMarks}+)|(\\p{Punct})")
|
Regex("(\\p{InCombiningDiacriticalMarks}+)|(\\p{Punct})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -34,18 +34,6 @@ fun <T> unlikelyToBeNull(value: T?) =
|
||||||
value!!
|
value!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a try expression to a [Result].
|
|
||||||
* @param block The code to execute
|
|
||||||
* @return A [Result] representing the outcome of [block]'s execution.
|
|
||||||
*/
|
|
||||||
inline fun <reified R> fallible(block: () -> R) =
|
|
||||||
try {
|
|
||||||
Result.success(block())
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Result.failure(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aliases a check to ensure that the given number is non-zero.
|
* Aliases a check to ensure that the given number is non-zero.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue