func()

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
}