in sort/multi_recall_mix_sort.go [61:170]
func (s *MultiRecallMixSort) doSort(sortData *SortData) error {
items := sortData.Data.([]*module.Item)
size := sortData.Context.Size
if s.size > size {
size = s.size
}
if len(items) < size {
return nil
}
result := make([]*module.Item, size)
strategies := s.createMixStrategies(sortData)
defaultStrategy := newDefaultStrategy(nil, size)
userProperties := sortData.User.MakeUserFeatures2()
found := false
for _, item := range items {
found = false
for _, strategy := range strategies {
if strategy.ContainsRecallName(item.GetRecallName()) {
found = true
strategy.AppendItem(item)
break
}
if strategy.IsUseCondition() {
properties := item.GetFeatures()
ok, err := strategy.EvaluateByDomain(userProperties, properties)
if err != nil {
log.Error(fmt.Sprintf("requestId=%s\tmodule=MultiRecallMixSort\titemId=%s\terror=%v", sortData.Context.RecommendId, item.Id, err))
break
}
if ok {
found = ok
strategy.AppendItem(item)
break
}
}
}
if !found {
defaultStrategy.AppendItem(item)
}
if defaultStrategy.IsFull() {
flag := true
for _, strategy := range strategies {
if !strategy.IsFull() {
flag = false
break
}
}
if flag {
break
}
}
}
for _, strategy := range strategies {
if strategy.GetStrategyType() == FixPositionStrategyType {
result = strategy.BuildItems(result)
}
}
for _, strategy := range strategies {
if strategy.GetStrategyType() == RandomPositionStrategyType {
result = strategy.BuildItems(result)
}
}
result = defaultStrategy.BuildItems(result)
size = len(result)
var iterator *remainItemIterator
for i := 0; i < size; i++ {
if result[i] == nil {
if iterator == nil {
iterator = newRemainItemIterator(result, items)
}
if item, exist := iterator.findRemainItem(); exist {
result[i] = item
} else {
result[i] = result[size-1]
result = result[:size-1]
i--
size--
}
}
}
if s.remainItem {
if iterator == nil {
iterator = newRemainItemIterator(result, items)
}
for {
if item, exist := iterator.findRemainItem(); exist {
result = append(result, item)
} else {
break
}
}
}
sortData.Data = result
return nil
}