refactor: reduce GC pressure by pre-allocating slices
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
+1
-1
@@ -84,7 +84,7 @@ type Albums []Album
|
|||||||
// It assumes all albums have the same AlbumArtist, or else results are unpredictable.
|
// It assumes all albums have the same AlbumArtist, or else results are unpredictable.
|
||||||
func (als Albums) ToAlbumArtist() Artist {
|
func (als Albums) ToAlbumArtist() Artist {
|
||||||
a := Artist{AlbumCount: len(als)}
|
a := Artist{AlbumCount: len(als)}
|
||||||
var mbzArtistIds []string
|
mbzArtistIds := make([]string, 0, len(als))
|
||||||
for _, al := range als {
|
for _, al := range als {
|
||||||
a.ID = al.AlbumArtistID
|
a.ID = al.AlbumArtistID
|
||||||
a.Name = al.AlbumArtist
|
a.Name = al.AlbumArtist
|
||||||
|
|||||||
+2
-2
@@ -39,11 +39,11 @@ func ToLyrics(language, text string) (*Lyrics, error) {
|
|||||||
text = str.SanitizeText(text)
|
text = str.SanitizeText(text)
|
||||||
|
|
||||||
lines := strings.Split(text, "\n")
|
lines := strings.Split(text, "\n")
|
||||||
|
structuredLines := make([]Line, 0, len(lines)*2)
|
||||||
|
|
||||||
artist := ""
|
artist := ""
|
||||||
title := ""
|
title := ""
|
||||||
var offset *int64 = nil
|
var offset *int64 = nil
|
||||||
structuredLines := []Line{}
|
|
||||||
|
|
||||||
synced := syncRegex.MatchString(text)
|
synced := syncRegex.MatchString(text)
|
||||||
priorLine := ""
|
priorLine := ""
|
||||||
@@ -105,7 +105,7 @@ func ToLyrics(language, text string) (*Lyrics, error) {
|
|||||||
Value: strings.TrimSpace(priorLine),
|
Value: strings.TrimSpace(priorLine),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
timestamps = []int64{}
|
timestamps = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
end := 0
|
end := 0
|
||||||
|
|||||||
+13
-15
@@ -108,11 +108,9 @@ type MediaFiles []MediaFile
|
|||||||
|
|
||||||
// Dirs returns a deduped list of all directories from the MediaFiles' paths
|
// Dirs returns a deduped list of all directories from the MediaFiles' paths
|
||||||
func (mfs MediaFiles) Dirs() []string {
|
func (mfs MediaFiles) Dirs() []string {
|
||||||
var dirs []string
|
dirs := slice.Map(mfs, func(m MediaFile) string {
|
||||||
for _, mf := range mfs {
|
return filepath.Dir(m.Path)
|
||||||
dir, _ := filepath.Split(mf.Path)
|
})
|
||||||
dirs = append(dirs, filepath.Clean(dir))
|
|
||||||
}
|
|
||||||
slices.Sort(dirs)
|
slices.Sort(dirs)
|
||||||
return slices.Compact(dirs)
|
return slices.Compact(dirs)
|
||||||
}
|
}
|
||||||
@@ -121,16 +119,16 @@ func (mfs MediaFiles) Dirs() []string {
|
|||||||
// It assumes all mediafiles have the same Album, or else results are unpredictable.
|
// It assumes all mediafiles have the same Album, or else results are unpredictable.
|
||||||
func (mfs MediaFiles) ToAlbum() Album {
|
func (mfs MediaFiles) ToAlbum() Album {
|
||||||
a := Album{SongCount: len(mfs)}
|
a := Album{SongCount: len(mfs)}
|
||||||
var fullText []string
|
fullText := make([]string, 0, len(mfs))
|
||||||
var albumArtistIds []string
|
albumArtistIds := make([]string, 0, len(mfs))
|
||||||
var songArtistIds []string
|
songArtistIds := make([]string, 0, len(mfs))
|
||||||
var mbzAlbumIds []string
|
mbzAlbumIds := make([]string, 0, len(mfs))
|
||||||
var comments []string
|
comments := make([]string, 0, len(mfs))
|
||||||
var years []int
|
years := make([]int, 0, len(mfs))
|
||||||
var dates []string
|
dates := make([]string, 0, len(mfs))
|
||||||
var originalYears []int
|
originalYears := make([]int, 0, len(mfs))
|
||||||
var originalDates []string
|
originalDates := make([]string, 0, len(mfs))
|
||||||
var releaseDates []string
|
releaseDates := make([]string, 0, len(mfs))
|
||||||
for _, m := range mfs {
|
for _, m := range mfs {
|
||||||
// We assume these attributes are all the same for all songs on an album
|
// We assume these attributes are all the same for all songs on an album
|
||||||
a.ID = m.AlbumID
|
a.ID = m.AlbumID
|
||||||
|
|||||||
+294
-232
@@ -1,6 +1,7 @@
|
|||||||
package model_test
|
package model_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/navidrome/navidrome/conf"
|
"github.com/navidrome/navidrome/conf"
|
||||||
@@ -13,258 +14,319 @@ import (
|
|||||||
|
|
||||||
var _ = Describe("MediaFiles", func() {
|
var _ = Describe("MediaFiles", func() {
|
||||||
var mfs MediaFiles
|
var mfs MediaFiles
|
||||||
|
Describe("ToAlbum", func() {
|
||||||
Context("Simple attributes", func() {
|
Context("Simple attributes", func() {
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{
|
|
||||||
{
|
|
||||||
ID: "1", AlbumID: "AlbumID", Album: "Album", ArtistID: "ArtistID", Artist: "Artist", AlbumArtistID: "AlbumArtistID", AlbumArtist: "AlbumArtist",
|
|
||||||
SortAlbumName: "SortAlbumName", SortArtistName: "SortArtistName", SortAlbumArtistName: "SortAlbumArtistName",
|
|
||||||
OrderAlbumName: "OrderAlbumName", OrderAlbumArtistName: "OrderAlbumArtistName",
|
|
||||||
MbzAlbumArtistID: "MbzAlbumArtistID", MbzAlbumType: "MbzAlbumType", MbzAlbumComment: "MbzAlbumComment",
|
|
||||||
Compilation: false, CatalogNum: "", Path: "/music1/file1.mp3",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ID: "2", Album: "Album", ArtistID: "ArtistID", Artist: "Artist", AlbumArtistID: "AlbumArtistID", AlbumArtist: "AlbumArtist", AlbumID: "AlbumID",
|
|
||||||
SortAlbumName: "SortAlbumName", SortArtistName: "SortArtistName", SortAlbumArtistName: "SortAlbumArtistName",
|
|
||||||
OrderAlbumName: "OrderAlbumName", OrderArtistName: "OrderArtistName", OrderAlbumArtistName: "OrderAlbumArtistName",
|
|
||||||
MbzAlbumArtistID: "MbzAlbumArtistID", MbzAlbumType: "MbzAlbumType", MbzAlbumComment: "MbzAlbumComment",
|
|
||||||
Compilation: true, CatalogNum: "CatalogNum", HasCoverArt: true, Path: "/music2/file2.mp3",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
It("sets the single values correctly", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.ID).To(Equal("AlbumID"))
|
|
||||||
Expect(album.Name).To(Equal("Album"))
|
|
||||||
Expect(album.Artist).To(Equal("Artist"))
|
|
||||||
Expect(album.ArtistID).To(Equal("ArtistID"))
|
|
||||||
Expect(album.AlbumArtist).To(Equal("AlbumArtist"))
|
|
||||||
Expect(album.AlbumArtistID).To(Equal("AlbumArtistID"))
|
|
||||||
Expect(album.SortAlbumName).To(Equal("SortAlbumName"))
|
|
||||||
Expect(album.SortAlbumArtistName).To(Equal("SortAlbumArtistName"))
|
|
||||||
Expect(album.OrderAlbumName).To(Equal("OrderAlbumName"))
|
|
||||||
Expect(album.OrderAlbumArtistName).To(Equal("OrderAlbumArtistName"))
|
|
||||||
Expect(album.MbzAlbumArtistID).To(Equal("MbzAlbumArtistID"))
|
|
||||||
Expect(album.MbzAlbumType).To(Equal("MbzAlbumType"))
|
|
||||||
Expect(album.MbzAlbumComment).To(Equal("MbzAlbumComment"))
|
|
||||||
Expect(album.CatalogNum).To(Equal("CatalogNum"))
|
|
||||||
Expect(album.Compilation).To(BeTrue())
|
|
||||||
Expect(album.EmbedArtPath).To(Equal("/music2/file2.mp3"))
|
|
||||||
Expect(album.Paths).To(Equal("/music1" + consts.Zwsp + "/music2"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("Aggregated attributes", func() {
|
|
||||||
When("we have only one song", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{
|
|
||||||
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
It("calculates the aggregates correctly", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Duration).To(Equal(float32(100.2)))
|
|
||||||
Expect(album.Size).To(Equal(int64(1024)))
|
|
||||||
Expect(album.MinYear).To(Equal(1985))
|
|
||||||
Expect(album.MaxYear).To(Equal(1985))
|
|
||||||
Expect(album.Date).To(Equal("1985-01-02"))
|
|
||||||
Expect(album.UpdatedAt).To(Equal(t("2022-12-19 09:30")))
|
|
||||||
Expect(album.CreatedAt).To(Equal(t("2022-12-19 08:30")))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
When("we have multiple songs with different dates", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{
|
|
||||||
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
|
||||||
{Duration: 200.2, Size: 2048, Year: 0, Date: "", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 08:30")},
|
|
||||||
{Duration: 150.6, Size: 1000, Year: 1986, Date: "1986-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 07:30")},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
It("calculates the aggregates correctly", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Duration).To(Equal(float32(451.0)))
|
|
||||||
Expect(album.Size).To(Equal(int64(4072)))
|
|
||||||
Expect(album.MinYear).To(Equal(1985))
|
|
||||||
Expect(album.MaxYear).To(Equal(1986))
|
|
||||||
Expect(album.Date).To(BeEmpty())
|
|
||||||
Expect(album.UpdatedAt).To(Equal(t("2022-12-19 09:45")))
|
|
||||||
Expect(album.CreatedAt).To(Equal(t("2022-12-19 07:30")))
|
|
||||||
})
|
|
||||||
Context("MinYear", func() {
|
|
||||||
It("returns 0 when all values are 0", func() {
|
|
||||||
mfs = MediaFiles{{Year: 0}, {Year: 0}, {Year: 0}}
|
|
||||||
a := mfs.ToAlbum()
|
|
||||||
Expect(a.MinYear).To(Equal(0))
|
|
||||||
})
|
|
||||||
It("returns the smallest value from the list, not counting 0", func() {
|
|
||||||
mfs = MediaFiles{{Year: 2000}, {Year: 0}, {Year: 1999}}
|
|
||||||
a := mfs.ToAlbum()
|
|
||||||
Expect(a.MinYear).To(Equal(1999))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have multiple songs with same dates", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{
|
|
||||||
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
|
||||||
{Duration: 200.2, Size: 2048, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 08:30")},
|
|
||||||
{Duration: 150.6, Size: 1000, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 07:30")},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
It("sets the date field correctly", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Date).To(Equal("1985-01-02"))
|
|
||||||
Expect(album.MinYear).To(Equal(1985))
|
|
||||||
Expect(album.MaxYear).To(Equal(1985))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("Calculated attributes", func() {
|
|
||||||
Context("Discs", func() {
|
|
||||||
When("we have no discs", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Album: "Album1"}, {Album: "Album1"}, {Album: "Album1"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Discs", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Discs).To(BeEmpty())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have only one disc", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Discs", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Discs).To(Equal(Discs{1: "DiscSubtitle"}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have multiple discs", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}, {DiscNumber: 2, DiscSubtitle: "DiscSubtitle2"}, {DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Discs", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Discs).To(Equal(Discs{1: "DiscSubtitle", 2: "DiscSubtitle2"}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
Context("Genres", func() {
|
|
||||||
When("we have only one Genre", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Genres: Genres{{ID: "g1", Name: "Rock"}}}}
|
|
||||||
})
|
|
||||||
It("sets the correct Genre", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Genre).To(Equal("Rock"))
|
|
||||||
Expect(album.Genres).To(ConsistOf(Genre{ID: "g1", Name: "Rock"}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have multiple Genres", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Genres: Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}, {ID: "g3", Name: "Alternative"}}}}
|
|
||||||
})
|
|
||||||
It("sets the correct Genre", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Genre).To(Equal("Rock"))
|
|
||||||
Expect(album.Genres).To(Equal(Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}, {ID: "g3", Name: "Alternative"}}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have one predominant Genre", func() {
|
|
||||||
var album Album
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Genres: Genres{{ID: "g2", Name: "Punk"}, {ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}}}}
|
|
||||||
album = mfs.ToAlbum()
|
|
||||||
})
|
|
||||||
It("sets the correct Genre", func() {
|
|
||||||
Expect(album.Genre).To(Equal("Punk"))
|
|
||||||
})
|
|
||||||
It("removes duplications from Genres", func() {
|
|
||||||
Expect(album.Genres).To(Equal(Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("Comments", func() {
|
|
||||||
When("we have only one Comment", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Comment: "comment1"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Comment", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Comment).To(Equal("comment1"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have multiple equal comments", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Comment: "comment1"}, {Comment: "comment1"}, {Comment: "comment1"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Comment", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Comment).To(Equal("comment1"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
When("we have different comments", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{{Comment: "comment1"}, {Comment: "not the same"}, {Comment: "comment1"}}
|
|
||||||
})
|
|
||||||
It("sets the correct Genre", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.Comment).To(BeEmpty())
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("AllArtistIds", func() {
|
|
||||||
BeforeEach(func() {
|
|
||||||
mfs = MediaFiles{
|
|
||||||
{AlbumArtistID: "22", ArtistID: "11"},
|
|
||||||
{AlbumArtistID: "22", ArtistID: "33"},
|
|
||||||
{AlbumArtistID: "22", ArtistID: "11"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
It("removes duplications", func() {
|
|
||||||
album := mfs.ToAlbum()
|
|
||||||
Expect(album.AllArtistIDs).To(Equal("11 22 33"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Context("FullText", func() {
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
mfs = MediaFiles{
|
mfs = MediaFiles{
|
||||||
{
|
{
|
||||||
Album: "Album1", AlbumArtist: "AlbumArtist1", Artist: "Artist1", DiscSubtitle: "DiscSubtitle1",
|
ID: "1", AlbumID: "AlbumID", Album: "Album", ArtistID: "ArtistID", Artist: "Artist", AlbumArtistID: "AlbumArtistID", AlbumArtist: "AlbumArtist",
|
||||||
SortAlbumName: "SortAlbumName1", SortAlbumArtistName: "SortAlbumArtistName1", SortArtistName: "SortArtistName1",
|
SortAlbumName: "SortAlbumName", SortArtistName: "SortArtistName", SortAlbumArtistName: "SortAlbumArtistName",
|
||||||
|
OrderAlbumName: "OrderAlbumName", OrderAlbumArtistName: "OrderAlbumArtistName",
|
||||||
|
MbzAlbumArtistID: "MbzAlbumArtistID", MbzAlbumType: "MbzAlbumType", MbzAlbumComment: "MbzAlbumComment",
|
||||||
|
Compilation: false, CatalogNum: "", Path: "/music1/file1.mp3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Album: "Album1", AlbumArtist: "AlbumArtist1", Artist: "Artist2", DiscSubtitle: "DiscSubtitle2",
|
ID: "2", Album: "Album", ArtistID: "ArtistID", Artist: "Artist", AlbumArtistID: "AlbumArtistID", AlbumArtist: "AlbumArtist", AlbumID: "AlbumID",
|
||||||
SortAlbumName: "SortAlbumName1", SortAlbumArtistName: "SortAlbumArtistName1", SortArtistName: "SortArtistName2",
|
SortAlbumName: "SortAlbumName", SortArtistName: "SortArtistName", SortAlbumArtistName: "SortAlbumArtistName",
|
||||||
|
OrderAlbumName: "OrderAlbumName", OrderArtistName: "OrderArtistName", OrderAlbumArtistName: "OrderAlbumArtistName",
|
||||||
|
MbzAlbumArtistID: "MbzAlbumArtistID", MbzAlbumType: "MbzAlbumType", MbzAlbumComment: "MbzAlbumComment",
|
||||||
|
Compilation: true, CatalogNum: "CatalogNum", HasCoverArt: true, Path: "/music2/file2.mp3",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
It("fills the fullText attribute correctly", func() {
|
|
||||||
|
It("sets the single values correctly", func() {
|
||||||
album := mfs.ToAlbum()
|
album := mfs.ToAlbum()
|
||||||
Expect(album.FullText).To(Equal(" album1 albumartist1 artist1 artist2 discsubtitle1 discsubtitle2 sortalbumartistname1 sortalbumname1 sortartistname1 sortartistname2"))
|
Expect(album.ID).To(Equal("AlbumID"))
|
||||||
|
Expect(album.Name).To(Equal("Album"))
|
||||||
|
Expect(album.Artist).To(Equal("Artist"))
|
||||||
|
Expect(album.ArtistID).To(Equal("ArtistID"))
|
||||||
|
Expect(album.AlbumArtist).To(Equal("AlbumArtist"))
|
||||||
|
Expect(album.AlbumArtistID).To(Equal("AlbumArtistID"))
|
||||||
|
Expect(album.SortAlbumName).To(Equal("SortAlbumName"))
|
||||||
|
Expect(album.SortAlbumArtistName).To(Equal("SortAlbumArtistName"))
|
||||||
|
Expect(album.OrderAlbumName).To(Equal("OrderAlbumName"))
|
||||||
|
Expect(album.OrderAlbumArtistName).To(Equal("OrderAlbumArtistName"))
|
||||||
|
Expect(album.MbzAlbumArtistID).To(Equal("MbzAlbumArtistID"))
|
||||||
|
Expect(album.MbzAlbumType).To(Equal("MbzAlbumType"))
|
||||||
|
Expect(album.MbzAlbumComment).To(Equal("MbzAlbumComment"))
|
||||||
|
Expect(album.CatalogNum).To(Equal("CatalogNum"))
|
||||||
|
Expect(album.Compilation).To(BeTrue())
|
||||||
|
Expect(album.EmbedArtPath).To(Equal("/music2/file2.mp3"))
|
||||||
|
Expect(album.Paths).To(Equal("/music1" + consts.Zwsp + "/music2"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Context("MbzAlbumID", func() {
|
Context("Aggregated attributes", func() {
|
||||||
When("we have only one MbzAlbumID", func() {
|
When("we have only one song", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
mfs = MediaFiles{{MbzAlbumID: "id1"}}
|
mfs = MediaFiles{
|
||||||
|
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
It("sets the correct MbzAlbumID", func() {
|
It("calculates the aggregates correctly", func() {
|
||||||
album := mfs.ToAlbum()
|
album := mfs.ToAlbum()
|
||||||
Expect(album.MbzAlbumID).To(Equal("id1"))
|
Expect(album.Duration).To(Equal(float32(100.2)))
|
||||||
|
Expect(album.Size).To(Equal(int64(1024)))
|
||||||
|
Expect(album.MinYear).To(Equal(1985))
|
||||||
|
Expect(album.MaxYear).To(Equal(1985))
|
||||||
|
Expect(album.Date).To(Equal("1985-01-02"))
|
||||||
|
Expect(album.UpdatedAt).To(Equal(t("2022-12-19 09:30")))
|
||||||
|
Expect(album.CreatedAt).To(Equal(t("2022-12-19 08:30")))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
When("we have multiple MbzAlbumID", func() {
|
|
||||||
|
When("we have multiple songs with different dates", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
mfs = MediaFiles{{MbzAlbumID: "id1"}, {MbzAlbumID: "id2"}, {MbzAlbumID: "id1"}}
|
mfs = MediaFiles{
|
||||||
|
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
||||||
|
{Duration: 200.2, Size: 2048, Year: 0, Date: "", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 08:30")},
|
||||||
|
{Duration: 150.6, Size: 1000, Year: 1986, Date: "1986-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 07:30")},
|
||||||
|
}
|
||||||
})
|
})
|
||||||
It("sets the correct MbzAlbumID", func() {
|
It("calculates the aggregates correctly", func() {
|
||||||
album := mfs.ToAlbum()
|
album := mfs.ToAlbum()
|
||||||
Expect(album.MbzAlbumID).To(Equal("id1"))
|
Expect(album.Duration).To(Equal(float32(451.0)))
|
||||||
|
Expect(album.Size).To(Equal(int64(4072)))
|
||||||
|
Expect(album.MinYear).To(Equal(1985))
|
||||||
|
Expect(album.MaxYear).To(Equal(1986))
|
||||||
|
Expect(album.Date).To(BeEmpty())
|
||||||
|
Expect(album.UpdatedAt).To(Equal(t("2022-12-19 09:45")))
|
||||||
|
Expect(album.CreatedAt).To(Equal(t("2022-12-19 07:30")))
|
||||||
})
|
})
|
||||||
|
Context("MinYear", func() {
|
||||||
|
It("returns 0 when all values are 0", func() {
|
||||||
|
mfs = MediaFiles{{Year: 0}, {Year: 0}, {Year: 0}}
|
||||||
|
a := mfs.ToAlbum()
|
||||||
|
Expect(a.MinYear).To(Equal(0))
|
||||||
|
})
|
||||||
|
It("returns the smallest value from the list, not counting 0", func() {
|
||||||
|
mfs = MediaFiles{{Year: 2000}, {Year: 0}, {Year: 1999}}
|
||||||
|
a := mfs.ToAlbum()
|
||||||
|
Expect(a.MinYear).To(Equal(1999))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have multiple songs with same dates", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{Duration: 100.2, Size: 1024, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:30"), CreatedAt: t("2022-12-19 08:30")},
|
||||||
|
{Duration: 200.2, Size: 2048, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 08:30")},
|
||||||
|
{Duration: 150.6, Size: 1000, Year: 1985, Date: "1985-01-02", UpdatedAt: t("2022-12-19 09:45"), CreatedAt: t("2022-12-19 07:30")},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("sets the date field correctly", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Date).To(Equal("1985-01-02"))
|
||||||
|
Expect(album.MinYear).To(Equal(1985))
|
||||||
|
Expect(album.MaxYear).To(Equal(1985))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("Calculated attributes", func() {
|
||||||
|
Context("Discs", func() {
|
||||||
|
When("we have no discs", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Album: "Album1"}, {Album: "Album1"}, {Album: "Album1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Discs", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Discs).To(BeEmpty())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have only one disc", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Discs", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Discs).To(Equal(Discs{1: "DiscSubtitle"}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have multiple discs", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}, {DiscNumber: 2, DiscSubtitle: "DiscSubtitle2"}, {DiscNumber: 1, DiscSubtitle: "DiscSubtitle"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Discs", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Discs).To(Equal(Discs{1: "DiscSubtitle", 2: "DiscSubtitle2"}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("Genres", func() {
|
||||||
|
When("we have only one Genre", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Genres: Genres{{ID: "g1", Name: "Rock"}}}}
|
||||||
|
})
|
||||||
|
It("sets the correct Genre", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Genre).To(Equal("Rock"))
|
||||||
|
Expect(album.Genres).To(ConsistOf(Genre{ID: "g1", Name: "Rock"}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have multiple Genres", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Genres: Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}, {ID: "g3", Name: "Alternative"}}}}
|
||||||
|
})
|
||||||
|
It("sets the correct Genre", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Genre).To(Equal("Rock"))
|
||||||
|
Expect(album.Genres).To(Equal(Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}, {ID: "g3", Name: "Alternative"}}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have one predominant Genre", func() {
|
||||||
|
var album Album
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Genres: Genres{{ID: "g2", Name: "Punk"}, {ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}}}}
|
||||||
|
album = mfs.ToAlbum()
|
||||||
|
})
|
||||||
|
It("sets the correct Genre", func() {
|
||||||
|
Expect(album.Genre).To(Equal("Punk"))
|
||||||
|
})
|
||||||
|
It("removes duplications from Genres", func() {
|
||||||
|
Expect(album.Genres).To(Equal(Genres{{ID: "g1", Name: "Rock"}, {ID: "g2", Name: "Punk"}}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("Comments", func() {
|
||||||
|
When("we have only one Comment", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Comment: "comment1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Comment", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Comment).To(Equal("comment1"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have multiple equal comments", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Comment: "comment1"}, {Comment: "comment1"}, {Comment: "comment1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Comment", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Comment).To(Equal("comment1"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have different comments", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{Comment: "comment1"}, {Comment: "not the same"}, {Comment: "comment1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct Genre", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.Comment).To(BeEmpty())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("AllArtistIds", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{AlbumArtistID: "22", ArtistID: "11"},
|
||||||
|
{AlbumArtistID: "22", ArtistID: "33"},
|
||||||
|
{AlbumArtistID: "22", ArtistID: "11"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("removes duplications", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.AllArtistIDs).To(Equal("11 22 33"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("FullText", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{
|
||||||
|
Album: "Album1", AlbumArtist: "AlbumArtist1", Artist: "Artist1", DiscSubtitle: "DiscSubtitle1",
|
||||||
|
SortAlbumName: "SortAlbumName1", SortAlbumArtistName: "SortAlbumArtistName1", SortArtistName: "SortArtistName1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Album: "Album1", AlbumArtist: "AlbumArtist1", Artist: "Artist2", DiscSubtitle: "DiscSubtitle2",
|
||||||
|
SortAlbumName: "SortAlbumName1", SortAlbumArtistName: "SortAlbumArtistName1", SortArtistName: "SortArtistName2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("fills the fullText attribute correctly", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.FullText).To(Equal(" album1 albumartist1 artist1 artist2 discsubtitle1 discsubtitle2 sortalbumartistname1 sortalbumname1 sortartistname1 sortartistname2"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("MbzAlbumID", func() {
|
||||||
|
When("we have only one MbzAlbumID", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{MbzAlbumID: "id1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct MbzAlbumID", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.MbzAlbumID).To(Equal("id1"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
When("we have multiple MbzAlbumID", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{{MbzAlbumID: "id1"}, {MbzAlbumID: "id2"}, {MbzAlbumID: "id1"}}
|
||||||
|
})
|
||||||
|
It("sets the correct MbzAlbumID", func() {
|
||||||
|
album := mfs.ToAlbum()
|
||||||
|
Expect(album.MbzAlbumID).To(Equal("id1"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Dirs", func() {
|
||||||
|
var mfs MediaFiles
|
||||||
|
|
||||||
|
When("there are no media files", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{}
|
||||||
|
})
|
||||||
|
It("returns an empty list", func() {
|
||||||
|
Expect(mfs.Dirs()).To(BeEmpty())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
When("there is one media file", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{Path: "/music/artist/album/song.mp3"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("returns the directory of the media file", func() {
|
||||||
|
Expect(mfs.Dirs()).To(Equal([]string{filepath.Clean("/music/artist/album")}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
When("there are multiple media files in the same directory", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{Path: "/music/artist/album/song1.mp3"},
|
||||||
|
{Path: "/music/artist/album/song2.mp3"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("returns a single directory", func() {
|
||||||
|
Expect(mfs.Dirs()).To(Equal([]string{filepath.Clean("/music/artist/album")}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
When("there are multiple media files in different directories", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{Path: "/music/artist2/album/song2.mp3"},
|
||||||
|
{Path: "/music/artist1/album/song1.mp3"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("returns all directories", func() {
|
||||||
|
Expect(mfs.Dirs()).To(Equal([]string{filepath.Clean("/music/artist1/album"), filepath.Clean("/music/artist2/album")}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
When("there are media files with empty paths", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
mfs = MediaFiles{
|
||||||
|
{Path: ""},
|
||||||
|
{Path: "/music/artist/album/song.mp3"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
It("ignores the empty paths", func() {
|
||||||
|
Expect(mfs.Dirs()).To(Equal([]string{".", filepath.Clean("/music/artist/album")}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -140,11 +140,12 @@ func (r sqlRepository) buildSortOrder(sort, order string) string {
|
|||||||
reverseOrder = "desc"
|
reverseOrder = "desc"
|
||||||
}
|
}
|
||||||
|
|
||||||
var newSort []string
|
|
||||||
parts := strings.FieldsFunc(sort, splitFunc(','))
|
parts := strings.FieldsFunc(sort, splitFunc(','))
|
||||||
|
newSort := make([]string, 0, len(parts))
|
||||||
for _, p := range parts {
|
for _, p := range parts {
|
||||||
f := strings.FieldsFunc(p, splitFunc(' '))
|
f := strings.FieldsFunc(p, splitFunc(' '))
|
||||||
newField := []string{f[0]}
|
newField := make([]string, 1, len(f))
|
||||||
|
newField[0] = f[0]
|
||||||
if len(f) == 1 {
|
if len(f) == 1 {
|
||||||
newField = append(newField, order)
|
newField = append(newField, order)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -143,7 +143,7 @@ func (s MediaFileMapper) albumArtistID(md metadata.Tags) string {
|
|||||||
func (s MediaFileMapper) mapGenres(genres []string) (string, model.Genres) {
|
func (s MediaFileMapper) mapGenres(genres []string) (string, model.Genres) {
|
||||||
var result model.Genres
|
var result model.Genres
|
||||||
unique := map[string]struct{}{}
|
unique := map[string]struct{}{}
|
||||||
var all []string
|
all := make([]string, 0, len(genres)*2)
|
||||||
for i := range genres {
|
for i := range genres {
|
||||||
gs := strings.FieldsFunc(genres[i], func(r rune) bool {
|
gs := strings.FieldsFunc(genres[i], func(r rune) bool {
|
||||||
return strings.ContainsRune(conf.Server.Scanner.GenreSeparators, r)
|
return strings.ContainsRune(conf.Server.Scanner.GenreSeparators, r)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func NewTag(filePath string, fileInfo os.FileInfo, tags ParsedTags) Tags {
|
|||||||
func removeDuplicatesAndEmpty(values []string) []string {
|
func removeDuplicatesAndEmpty(values []string) []string {
|
||||||
encountered := map[string]struct{}{}
|
encountered := map[string]struct{}{}
|
||||||
empty := true
|
empty := true
|
||||||
var result []string
|
result := make([]string, 0, len(values))
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
if _, ok := encountered[v]; ok {
|
if _, ok := encountered[v]; ok {
|
||||||
continue
|
continue
|
||||||
@@ -300,7 +300,7 @@ func (t Tags) getFirstTagValue(tagNames ...string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t Tags) getAllTagValues(tagNames ...string) []string {
|
func (t Tags) getAllTagValues(tagNames ...string) []string {
|
||||||
var values []string
|
values := make([]string, 0, len(tagNames)*2)
|
||||||
for _, tag := range tagNames {
|
for _, tag := range tagNames {
|
||||||
if v, ok := t.Tags[tag]; ok {
|
if v, ok := t.Tags[tag]; ok {
|
||||||
values = append(values, v...)
|
values = append(values, v...)
|
||||||
@@ -311,7 +311,8 @@ func (t Tags) getAllTagValues(tagNames ...string) []string {
|
|||||||
|
|
||||||
func (t Tags) getSortTag(originalTag string, tagNames ...string) string {
|
func (t Tags) getSortTag(originalTag string, tagNames ...string) string {
|
||||||
formats := []string{"sort%s", "sort_%s", "sort-%s", "%ssort", "%s_sort", "%s-sort"}
|
formats := []string{"sort%s", "sort_%s", "sort-%s", "%ssort", "%s_sort", "%s-sort"}
|
||||||
all := []string{originalTag}
|
all := make([]string, 1, len(tagNames)*len(formats)+1)
|
||||||
|
all[0] = originalTag
|
||||||
for _, tag := range tagNames {
|
for _, tag := range tagNames {
|
||||||
for _, format := range formats {
|
for _, format := range formats {
|
||||||
name := fmt.Sprintf(format, tag)
|
name := fmt.Sprintf(format, tag)
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ func (s *TagScanner) processChangedDir(ctx context.Context, refresher *refresher
|
|||||||
|
|
||||||
// If track from folder is newer than the one in DB, select for update/insert in DB
|
// If track from folder is newer than the one in DB, select for update/insert in DB
|
||||||
log.Trace(ctx, "Processing changed folder", "dir", dir, "tracksInDB", len(currentTracks), "tracksInFolder", len(files))
|
log.Trace(ctx, "Processing changed folder", "dir", dir, "tracksInDB", len(currentTracks), "tracksInFolder", len(files))
|
||||||
var filesToUpdate []string
|
filesToUpdate := make([]string, 0, len(files))
|
||||||
for filePath, entry := range files {
|
for filePath, entry := range files {
|
||||||
c, inDB := currentTracks[filePath]
|
c, inDB := currentTracks[filePath]
|
||||||
if !inDB || fullScan {
|
if !inDB || fullScan {
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ func walkFolder(ctx context.Context, rootPath string, currentFolder string, resu
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadDir(ctx context.Context, dirPath string) ([]string, *dirStats, error) {
|
func loadDir(ctx context.Context, dirPath string) ([]string, *dirStats, error) {
|
||||||
var children []string
|
|
||||||
stats := &dirStats{}
|
stats := &dirStats{}
|
||||||
|
|
||||||
dirInfo, err := os.Stat(dirPath)
|
dirInfo, err := os.Stat(dirPath)
|
||||||
@@ -77,11 +76,13 @@ func loadDir(ctx context.Context, dirPath string) ([]string, *dirStats, error) {
|
|||||||
dir, err := os.Open(dirPath)
|
dir, err := os.Open(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(ctx, "Error in Opening directory", "path", dirPath, err)
|
log.Error(ctx, "Error in Opening directory", "path", dirPath, err)
|
||||||
return children, stats, err
|
return nil, stats, err
|
||||||
}
|
}
|
||||||
defer dir.Close()
|
defer dir.Close()
|
||||||
|
|
||||||
for _, entry := range fullReadDir(ctx, dir) {
|
entries := fullReadDir(ctx, dir)
|
||||||
|
children := make([]string, 0, len(entries))
|
||||||
|
for _, entry := range entries {
|
||||||
isDir, err := isDirOrSymlinkToDir(dirPath, entry)
|
isDir, err := isDirOrSymlinkToDir(dirPath, entry)
|
||||||
// Skip invalid symlinks
|
// Skip invalid symlinks
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Vendored
+2
-2
@@ -100,7 +100,7 @@ func (c *simpleCache[K, V]) evictExpired() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *simpleCache[K, V]) Keys() []K {
|
func (c *simpleCache[K, V]) Keys() []K {
|
||||||
var res []K
|
res := make([]K, 0, c.data.Len())
|
||||||
c.data.Range(func(item *ttlcache.Item[K, V]) bool {
|
c.data.Range(func(item *ttlcache.Item[K, V]) bool {
|
||||||
if !item.IsExpired() {
|
if !item.IsExpired() {
|
||||||
res = append(res, item.Key())
|
res = append(res, item.Key())
|
||||||
@@ -111,7 +111,7 @@ func (c *simpleCache[K, V]) Keys() []K {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *simpleCache[K, V]) Values() []V {
|
func (c *simpleCache[K, V]) Values() []V {
|
||||||
var res []V
|
res := make([]V, 0, c.data.Len())
|
||||||
c.data.Range(func(item *ttlcache.Item[K, V]) bool {
|
c.data.Range(func(item *ttlcache.Item[K, V]) bool {
|
||||||
if !item.IsExpired() {
|
if !item.IsExpired() {
|
||||||
res = append(res, item.Value())
|
res = append(res, item.Value())
|
||||||
|
|||||||
Reference in New Issue
Block a user