mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
playback: resolve shuffled windows without flat ID lists
This commit is contained in:
@@ -260,6 +260,22 @@ class QueueKeysetTest {
|
||||
assertTrue(ids.all { it in expected })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun thePlaylistWindowQuerySeeksThePositionIndex() =
|
||||
runTest {
|
||||
seedLibrary()
|
||||
val plan =
|
||||
queryPlan(
|
||||
"SELECT songs.*, playlist_songs.position AS playlistPosition, albums.coverArt AS coverArt " +
|
||||
"FROM playlist_songs JOIN songs ON songs.sourceId = playlist_songs.sourceId " +
|
||||
"AND songs.id = playlist_songs.songId LEFT JOIN albums ON albums.sourceId = songs.sourceId " +
|
||||
"AND albums.id = songs.albumId WHERE playlist_songs.sourceId = 1 " +
|
||||
"AND playlist_songs.playlistId = 'pl1' ORDER BY playlist_songs.position LIMIT 51 OFFSET 100000",
|
||||
)
|
||||
|
||||
assertTrue(plan.joinToString("\n"), plan.any { it.contains("sqlite_autoindex_playlist_songs_1") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun theAlbumKeysetQuerySeeksTheOrderIndex() =
|
||||
runTest {
|
||||
|
||||
@@ -727,6 +727,32 @@ class QueueRepositoryTest {
|
||||
assertEquals(listOf("s1", "s2", "s3"), resolveAll(restored))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shuffledLargeContextWindowOnlyResolvesRequestedRows() =
|
||||
runTest {
|
||||
seedLibrary()
|
||||
db.libraryDao().upsertPlaylists(listOf(playlist("huge", "Huge")))
|
||||
db.useWriterConnection { transactor ->
|
||||
transactor.usePrepared(
|
||||
"WITH RECURSIVE n(x) AS (VALUES(0) UNION ALL SELECT x + 1 FROM n WHERE x < 199999) " +
|
||||
"INSERT INTO playlist_songs SELECT 1, 'huge', 's1', x FROM n",
|
||||
) { statement ->
|
||||
statement.step()
|
||||
}
|
||||
}
|
||||
repository.snapshotAfter(listOf(repository.playlistEntry(1, "huge")))
|
||||
repository.setShuffle(42L)
|
||||
val snapshot = repository.snapshot()
|
||||
|
||||
val window = repository.window(snapshot, center = 100_000, radius = 25)
|
||||
|
||||
assertEquals(200_000L, snapshot.contextSize)
|
||||
assertEquals(51, window.size)
|
||||
assertEquals(51L, repository.resolvedRowCount)
|
||||
assertEquals((99_975L..100_025L).toList(), window.map { it.position })
|
||||
assertTrue(window.all { it.item.song.id == "s1" })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shuffledRangeResolvesEntriesInPositionOrder() =
|
||||
runTest {
|
||||
@@ -851,6 +877,37 @@ class QueueRepositoryTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contextIndexUsesTheFirstDuplicateOrdinalAcrossSparsePositions() =
|
||||
runTest {
|
||||
seedLibrary()
|
||||
db.libraryDao().upsertPlaylists(listOf(playlist("duplicates", "Duplicates")))
|
||||
db.libraryDao().upsertPlaylistSongs(
|
||||
listOf(
|
||||
PlaylistSong(1, "duplicates", "s2", 10),
|
||||
PlaylistSong(1, "duplicates", "s1", 20),
|
||||
PlaylistSong(1, "duplicates", "s2", 30),
|
||||
),
|
||||
)
|
||||
val snapshot = repository.snapshotAfter(listOf(repository.playlistEntry(1, "duplicates")))
|
||||
|
||||
assertEquals(0L, repository.combinedContextIndexOf(snapshot, "s2"))
|
||||
assertEquals(1L, repository.combinedContextIndexOf(snapshot, "s1"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun contextIndexFallsBackToBoundedRowsForGenre() =
|
||||
runTest {
|
||||
seedLibrary()
|
||||
insertGenre("s1", "Rock")
|
||||
insertGenre("s3", "Rock")
|
||||
insertGenre("s4", "Rock")
|
||||
val snapshot = repository.snapshotAfter(listOf(repository.genreEntry(1, "Rock")))
|
||||
|
||||
assertEquals(2L, repository.combinedContextIndexOf(snapshot, "s4"))
|
||||
assertTrue(repository.resolvedRowCount <= QUEUE_CHUNK)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun upNextCombinedIndexOfCountsFromTheAnchorIntoTheBlock() =
|
||||
runTest {
|
||||
|
||||
Reference in New Issue
Block a user