Files
TorrServerJellyfin/server/rutor/torrsearch/index.go
2023-01-29 20:30:59 +03:00

79 lines
1.5 KiB
Go

package torrsearch
import (
"server/log"
"server/rutor/models"
"strconv"
)
// Index is an inverted Index. It maps tokens to document IDs.
type Index map[string][]int
var idx Index
func NewIndex(torrs []*models.TorrentDetails) {
if len(torrs) > 0 {
log.TLogln("Index rutor db")
}
idx = make(Index)
idx.add(torrs)
}
func Search(text string) []int {
return idx.search(text)
}
func (idx Index) add(torrs []*models.TorrentDetails) {
for ID, torr := range torrs {
for _, token := range analyze(torr.Name + " " + torr.GetNames() + " " + strconv.Itoa(torr.Year)) {
ids := idx[token]
if ids != nil && ids[len(ids)-1] == ID {
// Don't add same ID twice.
continue
}
idx[token] = append(ids, ID)
}
}
}
// intersection returns the set intersection between a and b.
// a and b have to be sorted in ascending order and contain no duplicates.
func intersection(a []int, b []int) []int {
maxLen := len(a)
if len(b) > maxLen {
maxLen = len(b)
}
r := make([]int, 0, maxLen)
var i, j int
for i < len(a) && j < len(b) {
if a[i] < b[j] {
i++
} else if a[i] > b[j] {
j++
} else {
r = append(r, a[i])
i++
j++
}
}
return r
}
// Search queries the Index for the given text.
func (idx Index) search(text string) []int {
var r []int
for _, token := range analyze(text) {
if ids, ok := idx[token]; ok {
if r == nil {
r = ids
} else {
r = intersection(r, ids)
}
} else {
// Token doesn't exist.
return nil
}
}
return r
}