mirror of
https://github.com/navidrome/navidrome.git
synced 2026-08-01 07:21:17 +00:00
fix(album): make the cover art id collision-proof against updated_at drops
The additive id (updated_at + cover stamp) could re-emit a previously used value when updated_at decreases (the newest-mtime track leaves the album) by the same delta the cover stamp advanced — re-serving a stale client cover. Mix the timestamps instead, so the id changes whenever either does.
This commit is contained in:
parent
a79e670740
commit
5a90e17693
@ -50,6 +50,17 @@ var _ = Describe("Album", func() {
|
||||
a.CoverArtUpdatedAt = &stamp
|
||||
Expect(a.CoverArtID().String()).ToNot(Equal(before))
|
||||
})
|
||||
It("does not collide when updated_at decreases by the cover-stamp delta", func() {
|
||||
// With an additive combination, updated_at dropping by N while the cover
|
||||
// stamp advances by N re-emits the same id — the mix must not.
|
||||
u1 := time.Unix(1_000_000_000, 0)
|
||||
c1 := time.Unix(2_000_000_000, 0)
|
||||
u2 := u1.Add(-100 * time.Second)
|
||||
c2 := c1.Add(100 * time.Second)
|
||||
id1 := Album{ID: "al-1", UpdatedAt: u1, CoverArtUpdatedAt: &c1}.CoverArtID().String()
|
||||
id2 := Album{ID: "al-1", UpdatedAt: u2, CoverArtUpdatedAt: &c2}.CoverArtID().String()
|
||||
Expect(id1).ToNot(Equal(id2))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -112,11 +112,12 @@ func ParseDiscArtworkID(id string) (albumID string, discNumber int, err error) {
|
||||
}
|
||||
|
||||
func artworkIDFromAlbum(al Album) ArtworkID {
|
||||
// The suffix is a cache discriminator, not a date: cover edits are added (not max'd)
|
||||
// so the id changes even when updated_at is newer, e.g. files with future mtimes.
|
||||
// The suffix is a cache discriminator, not a date: mix (not max/add) the timestamps so
|
||||
// the id changes whenever either does — updated_at can decrease and cancel a plain sum.
|
||||
lastUpdate := al.UpdatedAt
|
||||
if al.CoverArtUpdatedAt != nil {
|
||||
lastUpdate = time.Unix(max(al.UpdatedAt.Unix(), 0)+al.CoverArtUpdatedAt.Unix(), 0)
|
||||
mixed := (uint64(al.UpdatedAt.Unix()) ^ (uint64(al.CoverArtUpdatedAt.Unix()) * 0x9E3779B97F4A7C15)) & 0x3FFFFFFFFFFFFFFF
|
||||
lastUpdate = time.Unix(int64(max(mixed, 1)), 0)
|
||||
}
|
||||
return ArtworkID{
|
||||
Kind: KindAlbumArtwork,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user