101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package backend
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
// SoundtrackData holds precomputed search data for a soundtrack
|
|
type SoundtrackData struct {
|
|
Original string
|
|
Lowercase string
|
|
Cleaned string
|
|
}
|
|
|
|
var (
|
|
searchCache []SoundtrackData
|
|
searchCacheMutex sync.Mutex
|
|
searchRegexCache = make(map[string]*regexp.Regexp)
|
|
searchRegexCacheMutex sync.Mutex
|
|
)
|
|
|
|
// GetSearchCache returns the precomputed search cache, initializing it if needed
|
|
func GetSearchCache() []SoundtrackData {
|
|
searchCacheMutex.Lock()
|
|
defer searchCacheMutex.Unlock()
|
|
|
|
if len(searchCache) == 0 {
|
|
loadSearchCache()
|
|
}
|
|
return searchCache
|
|
}
|
|
|
|
// ReloadSearchCache clears and reloads the search cache.
|
|
// This should be called after a sync operation to ensure search results are up to date.
|
|
func ReloadSearchCache() {
|
|
searchCacheMutex.Lock()
|
|
defer searchCacheMutex.Unlock()
|
|
searchCache = nil
|
|
loadSearchCache()
|
|
}
|
|
|
|
// loadSearchCache loads the soundtrack data into the cache
|
|
func loadSearchCache() {
|
|
soundtracks := GetAllSoundtracks()
|
|
searchCache = make([]SoundtrackData, len(soundtracks))
|
|
|
|
for i, soundtrack := range soundtracks {
|
|
cleaned := cleanSearchTerm(soundtrack)
|
|
lowercase := strings.ToLower(soundtrack)
|
|
searchCache[i] = SoundtrackData{
|
|
Original: soundtrack,
|
|
Lowercase: lowercase,
|
|
Cleaned: cleaned,
|
|
}
|
|
}
|
|
}
|
|
|
|
// CleanSearchTermForMatch cleans a search term for better matching
|
|
func CleanSearchTermForMatch(term string) string {
|
|
term = strings.ReplaceAll(term, " ", "")
|
|
term = strings.ReplaceAll(term, "é", "e")
|
|
term = strings.ReplaceAll(term, "+", "plus")
|
|
term = strings.ReplaceAll(term, "&", "and")
|
|
term = strings.ReplaceAll(term, "'n", "and")
|
|
return strings.ToLower(term)
|
|
}
|
|
|
|
// cleanSearchTerm cleans a search term for better matching (internal)
|
|
func cleanSearchTerm(term string) string {
|
|
return CleanSearchTermForMatch(term)
|
|
}
|
|
|
|
// MatchRegexCached checks if a search term matches using cached compiled regex
|
|
func MatchRegexCached(searchTerm string, soundtrackName string) bool {
|
|
if searchTerm == "" {
|
|
return true
|
|
}
|
|
|
|
// Check cache first
|
|
searchRegexCacheMutex.Lock()
|
|
re, exists := searchRegexCache[searchTerm]
|
|
if !exists {
|
|
re = compileSearchRegex(searchTerm)
|
|
searchRegexCache[searchTerm] = re
|
|
}
|
|
searchRegexCacheMutex.Unlock()
|
|
|
|
return re.MatchString(soundtrackName)
|
|
}
|
|
|
|
// compileSearchRegex compiles a search term into a regex pattern
|
|
func compileSearchRegex(searchTerm string) *regexp.Regexp {
|
|
regText := ".*"
|
|
for _, letter := range searchTerm {
|
|
regText += string(letter) + ".*"
|
|
}
|
|
re, _ := regexp.Compile(regText)
|
|
return re
|
|
}
|