Просмотр исходного кода

Merge branch 'cooperation_video_candidate_pool_improved_lld_0509' into test

刘立冬 2 дней назад
Родитель
Сommit
be479852e8

+ 13 - 7
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java

@@ -47,6 +47,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
+import java.time.LocalDate;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Executors;
@@ -698,8 +699,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
     }
     }
 
 
     /**
     /**
-     * 三路 1/1/1 严格穿插 + 跨路 video_id 去重。
-     * 缺路顺位补;先到先得(顺序:prior > posterior > hot)。
+     * 三路随机穿插 + 跨路 video_id 去重。
+     * 每步在未耗尽的池中等概率随机选一个,从该池头部取下一条(池内仍保持需求强度优先、组内 score DESC 的次序)。
+     * 用 (userId ^ 当天日期) 作为种子,保证同一用户当天翻页顺序一致、刷新一致。
      */
      */
     private Page<VideoContentItemVO> getInterleavedPage(VideoContentListParam param, ContentPlatformAccount user) {
     private Page<VideoContentItemVO> getInterleavedPage(VideoContentListParam param, ContentPlatformAccount user) {
         List<VideoContentItemVO> prior = fetchPriorCandidates(user, DEMAND_CANDIDATE_LIMIT);
         List<VideoContentItemVO> prior = fetchPriorCandidates(user, DEMAND_CANDIDATE_LIMIT);
@@ -715,13 +717,17 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         Set<Long> emittedIds = new HashSet<>();
         Set<Long> emittedIds = new HashSet<>();
         List<VideoContentItemVO> merged = new ArrayList<>();
         List<VideoContentItemVO> merged = new ArrayList<>();
 
 
-        int idx = 0;
+        long userSeed = user.getId() == null ? 0L : user.getId();
+        long seed = userSeed ^ LocalDate.now().toString().hashCode();
+        Random rng = new Random(seed);
+
         while (!(exhausted[0] && exhausted[1] && exhausted[2])) {
         while (!(exhausted[0] && exhausted[1] && exhausted[2])) {
-            int cur = idx % 3;
-            idx++;
-            if (exhausted[cur]) {
-                continue;
+            List<Integer> alive = new ArrayList<>(3);
+            for (int i = 0; i < 3; i++) {
+                if (!exhausted[i]) alive.add(i);
             }
             }
+            int cur = alive.get(rng.nextInt(alive.size()));
+
             List<VideoContentItemVO> pool = pools.get(cur);
             List<VideoContentItemVO> pool = pools.get(cur);
             while (pointers[cur] < pool.size() && emittedIds.contains(pool.get(pointers[cur]).getVideoId())) {
             while (pointers[cur] < pool.size() && emittedIds.contains(pool.get(pointers[cur]).getVideoId())) {
                 pointers[cur]++;
                 pointers[cur]++;