From f93d5f1a6950b9e7efa13fb81acd0c12cff86ced Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Wed, 27 Jul 2022 09:29:47 -0600 Subject: [PATCH] music: make string hashing more resillient Make string hashing a custom-made function that actually outputs to a long. This prevents overflows from causing a collision. --- .../java/org/oxycblt/auxio/music/Music.kt | 40 +++++++++++-------- .../playback/state/PlaybackStateManager.kt | 2 +- .../main/res/anim/nav_slide_enter_anim.xml | 9 ----- app/src/main/res/anim/nav_slide_exit_anim.xml | 9 ----- .../res/anim/nav_slide_pop_enter_anim.xml | 9 ----- .../main/res/anim/nav_slide_pop_exit_anim.xml | 9 ----- 6 files changed, 25 insertions(+), 53 deletions(-) delete mode 100644 app/src/main/res/anim/nav_slide_enter_anim.xml delete mode 100644 app/src/main/res/anim/nav_slide_exit_anim.xml delete mode 100644 app/src/main/res/anim/nav_slide_pop_enter_anim.xml delete mode 100644 app/src/main/res/anim/nav_slide_pop_exit_anim.xml diff --git a/app/src/main/java/org/oxycblt/auxio/music/Music.kt b/app/src/main/java/org/oxycblt/auxio/music/Music.kt index c4d512211..af23a6f0a 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Music.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Music.kt @@ -21,7 +21,6 @@ package org.oxycblt.auxio.music import android.content.Context import android.net.Uri -import android.provider.MediaStore import kotlin.math.max import kotlin.math.min import org.oxycblt.auxio.BuildConfig @@ -112,11 +111,9 @@ data class Song( ) : Music() { override val id: Long get() { - var result = rawName.lowercase().hashCode().toLong() - result = 31 * result + album.rawName.lowercase().hashCode() - result = - 31 * result + - (album.artist.rawName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode() + var result = rawName.toMusicId() + result = 31 * result + album.rawName.toMusicId() + result = 31 * result + album.artist.rawName.toMusicId() result = 31 * result + (track ?: 0) result = 31 * result + (disc ?: 0) result = 31 * result + durationMs @@ -156,15 +153,14 @@ data class Song( /** Internal field. Do not use. */ val _albumGroupingId: Long get() { - var result = - (_artistGroupingName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode().toLong() - result = 31 * result + _albumName.lowercase().hashCode() + var result = _artistGroupingName.toMusicId() + result = 31 * result + _albumName.toMusicId() return result } /** Internal field. Do not use. */ val _genreGroupingId: Long - get() = (_genreName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode().toLong() + get() = _genreName.toMusicId() /** Internal field. Do not use. */ val _artistGroupingName: String? @@ -228,9 +224,8 @@ data class Album( override val id: Long get() { - var result = rawName.lowercase().hashCode().toLong() - result = - 31 * result + (artist.rawName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode() + var result = rawName.toMusicId() + result = 31 * result + artist.rawName.toMusicId() result = 31 * result + (date?.year ?: 0) return result } @@ -244,7 +239,7 @@ data class Album( /** Internal field. Do not use. */ val _artistGroupingId: Long - get() = (_artistGroupingName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode().toLong() + get() = _artistGroupingName.toMusicId() /** Internal field. Do not use. */ val _isMissingArtist: Boolean @@ -273,7 +268,7 @@ data class Artist( } override val id: Long - get() = (rawName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode().toLong() + get() = rawName.toMusicId() override fun resolveName(context: Context) = rawName ?: context.getString(R.string.def_artist) @@ -294,11 +289,24 @@ data class Genre(override val rawName: String?, override val songs: List) get() = rawName override val id: Long - get() = (rawName?.lowercase() ?: MediaStore.UNKNOWN_STRING).hashCode().toLong() + get() = rawName.toMusicId() override fun resolveName(context: Context) = rawName ?: context.getString(R.string.def_genre) } +private fun String?.toMusicId(): Long { + if (this == null) { + // Pre-calculated hash of MediaStore.UNKNOWN_STRING + return 54493231833456 + } + + var result = 0L + for (ch in lowercase()) { + result = 31 * result + ch.code + } + return result +} + /** * An ISO-8601/RFC 3339 Date. * diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 66dc8fcbc..5dabd54f2 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -538,7 +538,7 @@ class PlaybackStateManager private constructor() { /** Called when the queue has changed in a way that does not change the index or song. */ fun onQueueChanged(queue: List) {} - /** Called when the queue and index has changed, but the song has not changed.. */ + /** Called when the queue and index has changed, but the song has not changed. */ fun onQueueReworked(index: Int, queue: List) {} /** Called when playback is changed completely, with a new index, queue, and parent. */ diff --git a/app/src/main/res/anim/nav_slide_enter_anim.xml b/app/src/main/res/anim/nav_slide_enter_anim.xml deleted file mode 100644 index f5e26a8da..000000000 --- a/app/src/main/res/anim/nav_slide_enter_anim.xml +++ /dev/null @@ -1,9 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/anim/nav_slide_exit_anim.xml b/app/src/main/res/anim/nav_slide_exit_anim.xml deleted file mode 100644 index 5859dd2a9..000000000 --- a/app/src/main/res/anim/nav_slide_exit_anim.xml +++ /dev/null @@ -1,9 +0,0 @@ - - diff --git a/app/src/main/res/anim/nav_slide_pop_enter_anim.xml b/app/src/main/res/anim/nav_slide_pop_enter_anim.xml deleted file mode 100644 index 0282d5b94..000000000 --- a/app/src/main/res/anim/nav_slide_pop_enter_anim.xml +++ /dev/null @@ -1,9 +0,0 @@ - - diff --git a/app/src/main/res/anim/nav_slide_pop_exit_anim.xml b/app/src/main/res/anim/nav_slide_pop_exit_anim.xml deleted file mode 100644 index 5400793bd..000000000 --- a/app/src/main/res/anim/nav_slide_pop_exit_anim.xml +++ /dev/null @@ -1,9 +0,0 @@ - - \ No newline at end of file