|  | @@ -22,20 +22,20 @@ import com.tzld.piaoquan.recommend.server.service.recall.strategy.Region24HRecal
 | 
	
		
			
				|  |  |  import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionHRecallStrategy;
 | 
	
		
			
				|  |  |  import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionRelative24HDupRecallStrategy;
 | 
	
		
			
				|  |  |  import com.tzld.piaoquan.recommend.server.service.recall.strategy.RegionRelative24HRecallStrategy;
 | 
	
		
			
				|  |  | -import com.tzld.piaoquan.recommend.server.util.DateUtils;
 | 
	
		
			
				|  |  | +import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
 | 
	
		
			
				|  |  |  import com.tzld.piaoquan.recommend.server.util.JSONUtils;
 | 
	
		
			
				|  |  |  import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.RandomUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.data.redis.core.RedisTemplate;
 | 
	
		
			
				|  |  | -import org.springframework.data.redis.core.ZSetOperations;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.util.CollectionUtils;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.PostConstruct;
 | 
	
		
			
				|  |  |  import java.util.*;
 | 
	
		
			
				|  |  |  import java.util.concurrent.TimeUnit;
 | 
	
		
			
				|  |  | +import java.util.function.Consumer;
 | 
	
		
			
				|  |  |  import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
	
		
			
				|  | @@ -113,7 +113,7 @@ public class RecommendService {
 | 
	
		
			
				|  |  |                      .setAbCode(Strings.nullToEmpty(videos.get(i).getAbCode()))
 | 
	
		
			
				|  |  |                      .setVideoId(videos.get(i).getVideoId())
 | 
	
		
			
				|  |  |                      .setRovScore(videos.get(i).getRovScore())
 | 
	
		
			
				|  |  | -                    .setSortScore(videos.get(i).getRovScore())
 | 
	
		
			
				|  |  | +                    .setSortScore(videos.get(i).getSortScore())
 | 
	
		
			
				|  |  |                      .setFlowPool(Strings.nullToEmpty(videos.get(i).getFlowPool()))
 | 
	
		
			
				|  |  |                      .setIsInFlowPool(videos.get(i).isInFlowPool() ? 1 : 0)
 | 
	
		
			
				|  |  |                      .setRand(videos.get(i).getRand())
 | 
	
	
		
			
				|  | @@ -128,54 +128,48 @@ public class RecommendService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private RecommendResponse specialMidRecommend(RecommendRequest request) {
 | 
	
		
			
				|  |  | -        String keyNamePrefix = "special:videos:item:";
 | 
	
		
			
				|  |  | -        String dateStr = DateUtils.getCurrentDateStr("yyyyMMdd");
 | 
	
		
			
				|  |  | -        String specialKeyName = keyNamePrefix + dateStr;
 | 
	
		
			
				|  |  | -        if (!redisTemplate.hasKey(specialKeyName)) {
 | 
	
		
			
				|  |  | -            dateStr = DateUtils.getBeforeDaysDateStr("yyyyMMdd", 1);
 | 
	
		
			
				|  |  | -            specialKeyName = keyNamePrefix + dateStr;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        RecallParam recallParam = new RecallParam();
 | 
	
		
			
				|  |  | +        recallParam.setAppType(request.getAppType());
 | 
	
		
			
				|  |  | +        recallParam.setMid(request.getMid());
 | 
	
		
			
				|  |  | +        recallParam.setSpecialRecommend(true);
 | 
	
		
			
				|  |  | +        recallParam.setSize(request.getSize());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        String lastSpecialRecallKey = String.format("recall:last:special:%s:%s:%s", request.getAppType(), request.getMid(), dateStr);
 | 
	
		
			
				|  |  | -        String value = redisTemplate.opsForValue().get(lastSpecialRecallKey);
 | 
	
		
			
				|  |  | -        Long idx = 0L;
 | 
	
		
			
				|  |  | -        if (StringUtils.isNotBlank(value)) {
 | 
	
		
			
				|  |  | -            idx = redisTemplate.opsForZSet().reverseRank(specialKeyName, value);
 | 
	
		
			
				|  |  | -            if (idx == null) {
 | 
	
		
			
				|  |  | -                idx = 0L;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        RecallResult recallResult = recallService.recall(recallParam);
 | 
	
		
			
				|  |  | +        log.info("recallResult {}", recallResult);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        int getSize = request.getSize() * 5;
 | 
	
		
			
				|  |  | -        int freq = 0;
 | 
	
		
			
				|  |  | -        List<VideoProto> results = new ArrayList<>();
 | 
	
		
			
				|  |  | -        while (results.size() < request.getSize()) {
 | 
	
		
			
				|  |  | -            freq += 1;
 | 
	
		
			
				|  |  | -            if (freq > 2) {
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            Set<ZSetOperations.TypedTuple<String>> data = redisTemplate.opsForZSet().reverseRangeWithScores(specialKeyName, idx, idx + getSize - 1);
 | 
	
		
			
				|  |  | -            if (CollectionUtils.isEmpty(data)) {
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            idx += getSize;
 | 
	
		
			
				|  |  | -            data.stream().forEach(t ->
 | 
	
		
			
				|  |  | -                    results.add(VideoProto.newBuilder()
 | 
	
		
			
				|  |  | -                            .setVideoId(Long.getLong(t.getValue(), 0L))
 | 
	
		
			
				|  |  | -                            .setRovScore(t.getScore())
 | 
	
		
			
				|  |  | -                            .setAbCode("99999")
 | 
	
		
			
				|  |  | -                            .setPushFrom("special_mid_videos")
 | 
	
		
			
				|  |  | -                            .build())
 | 
	
		
			
				|  |  | -            );
 | 
	
		
			
				|  |  | +        RankParam rankParam = new RankParam();
 | 
	
		
			
				|  |  | +        rankParam.setRecallResult(recallResult);
 | 
	
		
			
				|  |  | +        rankParam.setSize(request.getSize());
 | 
	
		
			
				|  |  | +        rankParam.setSpecialRecommend(true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        RankResult rankResult = rankService.rank(rankParam);
 | 
	
		
			
				|  |  | +        log.info("rankResult {}", rankResult);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (rankResult == null || CollectionUtils.isEmpty(rankResult.getVideos())) {
 | 
	
		
			
				|  |  | +            return RecommendResponse.newBuilder()
 | 
	
		
			
				|  |  | +                    .setResult(Result.newBuilder().setCode(1).setMessage("success"))
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (StringUtils.isNotBlank(request.getMid()) && !CollectionUtils.isEmpty(results)) {
 | 
	
		
			
				|  |  | -            redisTemplate.opsForValue().set(lastSpecialRecallKey, String.valueOf(results.get(results.size() - 1).getVideoId()), 1, TimeUnit.DAYS);
 | 
	
		
			
				|  |  | +        // 只返回size条数据
 | 
	
		
			
				|  |  | +        List<Video> videos = rankResult.getVideos();
 | 
	
		
			
				|  |  | +        if (recallParam.getSize() < rankResult.getVideos().size()) {
 | 
	
		
			
				|  |  | +            videos = rankResult.getVideos().subList(0, recallParam.getSize());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (StringUtils.isNotBlank(request.getMid()) && !CollectionUtils.isEmpty(videos)) {
 | 
	
		
			
				|  |  | +            Video lastVideo = videos.get(videos.size() - 1);
 | 
	
		
			
				|  |  | +            redisTemplate.opsForValue().set(lastVideo.getLastVideoKey(), String.valueOf(lastVideo.getVideoId()), 1
 | 
	
		
			
				|  |  | +                    , TimeUnit.DAYS);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return RecommendResponse.newBuilder()
 | 
	
		
			
				|  |  |                  .setResult(Result.newBuilder().setCode(1).setMessage("success"))
 | 
	
		
			
				|  |  | -                .addAllVideo(results)
 | 
	
		
			
				|  |  | +                .addAllVideo(CommonCollectionUtils.toList(videos, v -> VideoProto.newBuilder()
 | 
	
		
			
				|  |  | +                        .setPushFrom(Strings.nullToEmpty(v.getPushFrom()))
 | 
	
		
			
				|  |  | +                        .setAbCode(Strings.nullToEmpty(v.getAbCode()))
 | 
	
		
			
				|  |  | +                        .setVideoId(v.getVideoId())
 | 
	
		
			
				|  |  | +                        .setRovScore(v.getRovScore())
 | 
	
		
			
				|  |  | +                        .build()))
 | 
	
		
			
				|  |  |                  .build();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -344,7 +338,8 @@ public class RecommendService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          preViewedService.updateCache(request.getAppType(), request.getMid(), videos);
 | 
	
		
			
				|  |  | -        updateLastVideoCache(request, param, videos);
 | 
	
		
			
				|  |  | +        updateLastVideoCache(videos);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          updateFlowPoolCache(request, param, videos);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -379,47 +374,22 @@ public class RecommendService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private void updateLastVideoCache(RecommendRequest request, RecommendParam param,
 | 
	
		
			
				|  |  | -                                      List<Video> videos) {
 | 
	
		
			
				|  |  | -        // 2 地域小时最后一个视频
 | 
	
		
			
				|  |  | -        for (int i = videos.size() - 1; i >= 0; i--) {
 | 
	
		
			
				|  |  | -            if (videos.get(i).getPushFrom().equals(RegionHRecallStrategy.PUSH_FORM)) {
 | 
	
		
			
				|  |  | -                redisTemplate.opsForValue().set(String.format(RegionHRecallStrategy.LAST_VIDEO_KEY_FORMAT,
 | 
	
		
			
				|  |  | -                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
 | 
	
		
			
				|  |  | -                        24, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        // 3 地域24小时最后一个视频
 | 
	
		
			
				|  |  | -        for (int i = videos.size() - 1; i >= 0; i--) {
 | 
	
		
			
				|  |  | -            if (videos.get(i).getPushFrom().equals(Region24HRecallStrategy.PUSH_FORM)) {
 | 
	
		
			
				|  |  | -                redisTemplate.opsForValue().set(String.format(Region24HRecallStrategy.LAST_VIDEO_KEY_FORMAT,
 | 
	
		
			
				|  |  | -                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
 | 
	
		
			
				|  |  | -                        24, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +    private void updateLastVideoCache(List<Video> videos) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // 4 地域相对24小时最后一个视频
 | 
	
		
			
				|  |  | -        for (int i = videos.size() - 1; i >= 0; i--) {
 | 
	
		
			
				|  |  | -            if (videos.get(i).getPushFrom().equals(RegionRelative24HRecallStrategy.PUSH_FORM)) {
 | 
	
		
			
				|  |  | -                redisTemplate.opsForValue().set(String.format(RegionRelative24HRecallStrategy.LAST_VIDEO_KEY_FORMAT,
 | 
	
		
			
				|  |  | -                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
 | 
	
		
			
				|  |  | -                        24, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | +        Consumer<String> consumer = (p) -> {
 | 
	
		
			
				|  |  | +            for (int i = videos.size() - 1; i >= 0; i--) {
 | 
	
		
			
				|  |  | +                if (videos.get(i).getPushFrom().equals(p)) {
 | 
	
		
			
				|  |  | +                    redisTemplate.opsForValue().set(videos.get(i).getLastVideoKey(), String.valueOf(videos.get(i).getVideoId()),
 | 
	
		
			
				|  |  | +                            24, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | +                    break;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        // 5 地域相对24小时最后一个视频
 | 
	
		
			
				|  |  | -        for (int i = videos.size() - 1; i >= 0; i--) {
 | 
	
		
			
				|  |  | -            if (videos.get(i).getPushFrom().equals(RegionRelative24HDupRecallStrategy.PUSH_FORM)) {
 | 
	
		
			
				|  |  | -                redisTemplate.opsForValue().set(String.format(RegionRelative24HDupRecallStrategy.LAST_VIDEO_KEY_FORMAT,
 | 
	
		
			
				|  |  | -                                request.getAppType(), request.getMid()), String.valueOf(videos.get(i).getVideoId()),
 | 
	
		
			
				|  |  | -                        24, TimeUnit.HOURS);
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        consumer.accept(RegionHRecallStrategy.PUSH_FORM);
 | 
	
		
			
				|  |  | +        consumer.accept(Region24HRecallStrategy.PUSH_FORM);
 | 
	
		
			
				|  |  | +        consumer.accept(RegionRelative24HRecallStrategy.PUSH_FORM);
 | 
	
		
			
				|  |  | +        consumer.accept(RegionRelative24HDupRecallStrategy.PUSH_FORM);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  }
 |