| 
					
				 | 
			
			
				@@ -2,6 +2,8 @@ package com.tzld.piaoquan.recommend.server.service; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.alibaba.fastjson.JSONObject; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.google.common.base.Strings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.tzld.piaoquan.recommend.server.common.enums.AppTypeEnum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.piaoquan.recommend.server.gen.common.Result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.piaoquan.recommend.server.gen.recommend.HomepageRecommendRequest; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import com.tzld.piaoquan.recommend.server.gen.recommend.HomepageRecommendResponse; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -73,11 +75,11 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @PostConstruct 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public void init() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ab_initial_config_map.put(0, "095"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ab_initial_config_map.put(4, "144"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ab_initial_config_map.put(5, "121"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ab_initial_config_map.put(18, "074"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ab_initial_config_map.put(19, "069"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_initial_config_map.put(AppTypeEnum.VLOG.getCode(), "095"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_initial_config_map.put(AppTypeEnum.LOVELIVE.getCode(), "144"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_initial_config_map.put(AppTypeEnum.LONGVIDEO.getCode(), "121"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_initial_config_map.put(AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode(), "074"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ab_initial_config_map.put(AppTypeEnum.ZUI_JING_QI.getCode(), "069"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ab_initial_config_map.put(-1, "095-1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -90,24 +92,26 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 && redisTemplate.opsForSet().isMember("special:mid", request.getMid())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return specialMidRecommend(request); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         HomepageRecommendParam param = genHomepageRecommendParam(request, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         log.info("genHomepageRecommendParam : {}", JSONUtils.toJson(param)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        List<Video> videos = videoRecommend(request, param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Video> videos = videoRecommend(param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         updateCache(request, param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 更新position 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         List<VideoProto> vps = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for (int i = 0; i < videos.size(); i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             vps.add(VideoProto.newBuilder() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .setPosition(i + 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .setPushFrom(videos.get(i).getPushFrom()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    .setAbCode(videos.get(i).getAbCode()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .setPushFrom(Strings.nullToEmpty(videos.get(i).getPushFrom())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .setAbCode(Strings.nullToEmpty(videos.get(i).getAbCode())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .setVideoId(videos.get(i).getVideoId()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .setRovScore(videos.get(i).getRovScore()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .setSortScore(videos.get(i).getRovScore()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .setFlowPool(Strings.nullToEmpty(videos.get(i).getFlowPool())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .setIsInFlowPool(videos.get(i).isInFlowPool() ? 1 : 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .setRand(videos.get(i).getRand()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     .build()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -118,128 +122,76 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void updateCache(HomepageRecommendRequest request, HomepageRecommendParam param, List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (StringUtils.isNotBlank(request.getMid()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                || CollectionUtils.isEmpty(videos)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 1 更新预曝光数据 过期时间 30min 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Long[] videoIds = new Long[videos.size()]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (int i = 0; i < videoIds.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            videoIds[i] = videos.get(i).getVideoId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private HomepageRecommendResponse specialMidRecommend(HomepageRecommendRequest 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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        preViewedService.updateCache(request.getAppType(), request.getMid(), videoIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        updateLastVideoCache(request, param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        updateFlowPoolCache(request, param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void updateFlowPoolCache(HomepageRecommendRequest request, HomepageRecommendParam param, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                     List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (request.getAppType() == 18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                || request.getAppType() == 19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                || CollectionUtils.isEmpty(videos)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            idx = idx == null ? 0L : idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        List<Video> flowPoolVideos = videos.stream() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .filter(v -> v.getPushFrom().equals(FlowPoolConstants.PUSH_FORM)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        switch (param.getFlow_pool_abtest_group()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                flowPoolService.updateLocalDistributeCountWithLevel(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            case FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL_SCORE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                flowPoolService.updateLocalDistributeCountWithLevelScore(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                flowPoolService.updateLocalDistributeCount(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int getSize = request.getSize() * 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int freq = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<VideoProto> results = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (results.size() < request.getSize()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            freq += 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (freq > 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void updateLastVideoCache(HomepageRecommendRequest request, HomepageRecommendParam param, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                      List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 2 地域小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 3 地域24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 4 地域相对24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 5 地域相对24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            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()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private List<Video> videoRecommend(HomepageRecommendRequest request, HomepageRecommendParam param) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        RecallParam recallParam = new RecallParam(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        RecallResult recallResult = recallService.recall(recallParam); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        RankParam rankParam = new RankParam(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        rankParam.setRecallResult(recallResult); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        RankResult result = rankService.rank(rankParam); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (result == null || CollectionUtils.isEmpty(result.getVideos())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return Collections.emptyList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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 = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (request.getSize() < result.getVideos().size()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return videos.subList(0, request.getSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return videos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return HomepageRecommendResponse.newBuilder() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .setResult(Result.newBuilder().setCode(1).setMessage("success")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .addAllVideo(results) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private HomepageRecommendParam genHomepageRecommendParam(HomepageRecommendRequest request, int recommendType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         HomepageRecommendParam param = new HomepageRecommendParam(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setTop_K(3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setTopK(3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         param.setFlowPoolP(0.3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setNo_op_flag(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setExpire_time(3600); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setOld_video_index(-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        String abInitialConfig = ab_initial_config_map.containsKey(request.getAppType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? ab_initial_config_map.get(request.getAppType()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : ab_initial_config_map.get(-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setMid(request.getMid()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setSize(request.getSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // client_info: {"cityCode": "", "provinceCode": "330000"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (StringUtils.isNotBlank(request.getClientInfo())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Map<String, String> clientInfoMap = JSONObject.parseObject(request.getClientInfo(), Map.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            param.setCityCode(clientInfoMap.get("cityCode")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            param.setProvinceCode(clientInfoMap.get("provinceCode")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String abInitialConfig = ab_initial_config_map.getOrDefault(request.getAppType(), "095-1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Map<String, String> abExpCode = abExpCodeMap.get(abInitialConfig); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setAb_code(abExpCode.get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setRule_key(abExpCode.get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setData_key(abExpCode.get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setRule_key_30day(abExpCode.get("30day_rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setShield_config(""); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        param.setRank_key_prefix("rank:score1:"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setAbCode(abExpCode.get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setRuleKey(abExpCode.get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setDataKey(abExpCode.get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        param.setRankKeyPrefix("rank:score1:"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 实验配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (StringUtils.isNotBlank(request.getAbExpInfo())) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -266,14 +218,12 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for (Map.Entry<String, Map<String, String>> entry : abExpCodeMap.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (abExpCodes.contains(entry.getKey())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setAb_code(entry.getValue().get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setRule_key(entry.getValue().get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setData_key(entry.getValue().get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setRank_key_prefix(StringUtils.isNotBlank(entry.getValue().get("rank_key_prefix")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setAbCode(entry.getValue().get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setRuleKey(entry.getValue().get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setDataKey(entry.getValue().get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setRankKeyPrefix(StringUtils.isNotBlank(entry.getValue().get("rank_key_prefix")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             ? entry.getValue().get("rank_key_prefix") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             : "rank:score1:"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setRule_key_30day(entry.getValue().get("30day_rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setShield_config(entry.getValue().get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -299,20 +249,20 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 String eventId = abInfoAppMap.get("10003"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Map<String, Map<String, String>> appAbCode = appAbCodeMap.get("10003"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (StringUtils.isNotBlank(eventId) && appAbCode.containsKey(eventId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setAb_code(appAbCode.get(eventId).get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setRule_key(appAbCode.get(eventId).get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    param.setData_key(appAbCode.get(eventId).get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setAbCode(appAbCode.get(eventId).get("ab_code")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setRuleKey(appAbCode.get(eventId).get("rule_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    param.setDataKey(appAbCode.get(eventId).get("data_key")); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // 流量池分发实验组划分 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             int flowPoolIdChoice = flowPoolIdList[RandomUtils.nextInt(0, flowPoolIdList.length - 1)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            param.setFlow_pool_abtest_group("control_group"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            param.setFlowPoolAbtestGroup("control_group"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Map<String, List<Integer>> flowPoolConfig = flowPoolConfigService.getFlowPoolConfig(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 for (Map.Entry<String, List<Integer>> entry : flowPoolConfig.entrySet()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     if (entry.getValue().contains(flowPoolIdChoice)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        param.setFlow_pool_abtest_group(entry.getKey()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        param.setFlowPoolAbtestGroup(entry.getKey()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } catch (Exception e) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -323,54 +273,163 @@ public class RecommendService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return param; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private HomepageRecommendResponse specialMidRecommend(HomepageRecommendRequest 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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private List<Video> videoRecommend(HomepageRecommendParam param) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RecallResult recallResult = recallService.recall(convertToRecallParam(param)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RankResult result = rankService.rank(convertToRankParam(param, recallResult)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (result == null || CollectionUtils.isEmpty(result.getVideos())) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return Collections.emptyList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            idx = idx == null ? 0L : idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 只返回size条数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Video> videos = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (param.getSize() < result.getVideos().size()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            videos = result.getVideos().subList(0, param.getSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            videos = result.getVideos(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int getSize = request.getSize() * 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int freq = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        List<VideoProto> results = new ArrayList<>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while (results.size() < request.getSize()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            freq += 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (freq > 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // mark video in flow pool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO 业务上有什么用处 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 需要被标记的视频满足什么条件 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        markFlowPoolVideo(param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return videos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private RecallParam convertToRecallParam(HomepageRecommendParam param) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RecallParam recallParam = new RecallParam(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setAppType(param.getAppType()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setAbCode(param.getAbCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setVideoId(param.getVideoId()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setFlowPoolAbtestGroup(param.getFlowPoolAbtestGroup()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setProvinceCode(param.getProvinceCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setCityCode(param.getCityCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setDataKey(param.getDataKey()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setRuleKey(param.getRuleKey()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setMid(param.getMid()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        recallParam.setSize(param.getSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return recallParam; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private RankParam convertToRankParam(HomepageRecommendParam param, RecallResult recallResult) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        RankParam rankParam = new RankParam(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setRecallResult(recallResult); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setAbCode(param.getAbCode()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setSize(param.getSize()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setFlowPoolP(param.getFlowPoolP()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setTopK(param.getTopK()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setRankKeyPrefix(param.getRankKeyPrefix()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        rankParam.setAppType(param.getAppType()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return rankParam; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void markFlowPoolVideo(HomepageRecommendParam param, List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (Video data : videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Long videoId = data.getVideoId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String quick_flow_pool_isin_flow_pool_key = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    String.format("flow:pool:quick:video:ids:%s:3", param.getAppType()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String quick_flow_pool_flow_pool_key = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    String.format("flow:pool:quick:video:%s:3:%s", param.getAppType(), videoId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (redisTemplate.opsForSet().isMember(quick_flow_pool_isin_flow_pool_key, videoId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                data.setFlowPool(redisTemplate.opsForSet().randomMember(quick_flow_pool_flow_pool_key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                data.setInFlowPool(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String isIn_flow_pool_key = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        String.format("flow:pool:video:ids:%s:3", param.getAppType()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String flow_pool_key = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        String.format("flow:pool:video:%s:%s", param.getAppType(), videoId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (redisTemplate.opsForSet().isMember(isIn_flow_pool_key, videoId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    data.setFlowPool(redisTemplate.opsForSet().randomMember(flow_pool_key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    data.setInFlowPool(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Set<ZSetOperations.TypedTuple<String>> data = redisTemplate.opsForZSet().reverseRangeWithScores(specialKeyName, idx, idx + getSize - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (CollectionUtils.isEmpty(data)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void updateCache(HomepageRecommendRequest request, HomepageRecommendParam param, List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (StringUtils.isNotBlank(request.getMid()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || CollectionUtils.isEmpty(videos)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 1 更新预曝光数据 过期时间 30min 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Long[] videoIds = new Long[videos.size()]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = 0; i < videoIds.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            videoIds[i] = videos.get(i).getVideoId(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        preViewedService.updateCache(request.getAppType(), request.getMid(), videoIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        updateLastVideoCache(request, param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        updateFlowPoolCache(request, param, videos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void updateFlowPoolCache(HomepageRecommendRequest request, HomepageRecommendParam param, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                     List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (request.getAppType() == 18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || request.getAppType() == 19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                || CollectionUtils.isEmpty(videos)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        List<Video> flowPoolVideos = videos.stream() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .filter(v -> v.getPushFrom().equals(FlowPoolConstants.PUSH_FORM)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .collect(Collectors.toList()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (param.getFlowPoolAbtestGroup()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                flowPoolService.updateLocalDistributeCountWithLevel(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL_SCORE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                flowPoolService.updateLocalDistributeCountWithLevelScore(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                flowPoolService.updateLocalDistributeCount(flowPoolVideos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void updateLastVideoCache(HomepageRecommendRequest request, HomepageRecommendParam param, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      List<Video> videos) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 2 地域小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            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()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (StringUtils.isNotBlank(request.getMid()) && !CollectionUtils.isEmpty(results)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            redisTemplate.opsForValue().set(lastSpecialRecallKey, String.valueOf(results.get(results.size() - 1).getVideoId()), 1, TimeUnit.DAYS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 3 地域24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return HomepageRecommendResponse.newBuilder() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .setResult(Result.newBuilder().setCode(1).setMessage("success")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .addAllVideo(results) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .build(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 4 地域相对24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 5 地域相对24小时最后一个视频 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (int i = videos.size() - 1; i >= 0; i--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (videos.get(i).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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static void main(String[] args) { 
			 |