@@ -0,0 +1,112 @@
|
||||
package vidhkwsearcher
|
||||
|
||||
import (
|
||||
"91porn-server/common/constant"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"91porn-server/app/service/searcher"
|
||||
"91porn-server/app/service/searcher/vidsearcher"
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/models/s/kwrankmod"
|
||||
)
|
||||
|
||||
// VidHKWSearcher VidHKWSearcher
|
||||
type VidHKWSearcher struct {
|
||||
uid uint64
|
||||
vidOpt searcher.Opter
|
||||
}
|
||||
|
||||
// NewVidHKWSearcher NewVidHKWSearcher
|
||||
func NewVidHKWSearcher(uid uint64, vidOpt searcher.Opter) searcher.Searcher {
|
||||
return &VidHKWSearcher{
|
||||
uid: uid,
|
||||
vidOpt: vidOpt,
|
||||
}
|
||||
}
|
||||
|
||||
type pair struct {
|
||||
Word string
|
||||
Result searcher.Resulter
|
||||
}
|
||||
|
||||
const timeout = 3 * time.Second
|
||||
const gorouCountMax = 20
|
||||
|
||||
// Search Search
|
||||
func (v *VidHKWSearcher) Search(unuse searcher.KeyWorder, opt searcher.Opter) (result searcher.Resulter, err error) {
|
||||
limitEx1 := opt.Limit() + 1
|
||||
//获取热词
|
||||
words, err := kwrankmod.RecentRanking(limitEx1)
|
||||
if err != nil {
|
||||
return nil, errors.New("vidhkwsearcher RecentRanking error")
|
||||
}
|
||||
//没有热词
|
||||
if len(words) == 0 {
|
||||
return &Result{[]VideoRes{}, false}, nil
|
||||
}
|
||||
hasNext := false
|
||||
if len(words) > int(opt.Limit()) {
|
||||
words = words[:opt.Limit()]
|
||||
hasNext = true
|
||||
}
|
||||
gorouCount := opt.Limit()
|
||||
if gorouCount > gorouCountMax {
|
||||
gorouCount = gorouCountMax
|
||||
}
|
||||
ch := make(chan pair, gorouCount)
|
||||
err_ch := make(chan error)
|
||||
for _, w := range words {
|
||||
word := w.KeyWord
|
||||
common.Go(func() {
|
||||
k := &searcher.Keyword{Word: word}
|
||||
result, err := vidsearcher.NewVidSearcher(v.uid, constant.SearchSP, 0).Search(k, v.vidOpt)
|
||||
if err != nil {
|
||||
err_ch <- err
|
||||
return
|
||||
}
|
||||
pair := pair{
|
||||
Word: word,
|
||||
Result: result,
|
||||
}
|
||||
ch <- pair
|
||||
})
|
||||
}
|
||||
count := len(words)
|
||||
resultMap := make(map[string]searcher.Resulter, count)
|
||||
timer := time.NewTimer(timeout)
|
||||
for i := 0; i < count; i++ {
|
||||
timer.Reset(timeout)
|
||||
select {
|
||||
case pair := <-ch:
|
||||
resultMap[pair.Word] = pair.Result
|
||||
if i == count-1 {
|
||||
return toResult(words, v.vidOpt.Limit(), resultMap, hasNext), nil
|
||||
}
|
||||
case err := <-err_ch: //获取出错前搜索到的视屏
|
||||
log.Error(fmt.Sprintf("VidKWSearcher error:%+v\n", err))
|
||||
return toResult(words, v.vidOpt.Limit(), resultMap, hasNext), nil
|
||||
case <-timer.C: //获取超时前搜索到的视屏
|
||||
log.Warn(fmt.Sprintf("VidKWSearcher timeout::%+v\n", timeout))
|
||||
return toResult(words, v.vidOpt.Limit(), resultMap, hasNext), nil
|
||||
}
|
||||
}
|
||||
return &Result{[]VideoRes{}, false}, nil
|
||||
}
|
||||
|
||||
func toResult(words []kwrankmod.Keyword, vidCountPer int64, resultMap map[string]searcher.Resulter, hasNext bool) searcher.Resulter {
|
||||
resList := make([]VideoRes, 0, vidCountPer)
|
||||
//还原视屏的排序
|
||||
for _, w := range words {
|
||||
word := w.KeyWord
|
||||
result, ok := resultMap[word]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
videoList := result.Data().([]VideoRes)
|
||||
resList = append(resList, videoList...)
|
||||
}
|
||||
return &Result{resList, hasNext}
|
||||
}
|
||||
Reference in New Issue
Block a user