فهرست منبع

homepage recommend

丁云鹏 1 سال پیش
والد
کامیت
5d593ce681
34فایلهای تغییر یافته به همراه821 افزوده شده و 534 حذف شده
  1. 10 9
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java
  2. 268 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoProto.java
  3. 24 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoProtoOrBuilder.java
  4. 4 0
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto
  5. 12 11
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/HomepageRecommendParam.java
  6. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/Video.java
  7. 221 162
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java
  8. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolConstants.java
  9. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java
  10. 111 62
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java
  11. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java
  12. 14 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallResult.java
  13. 127 98
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java
  14. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallStrategy.java
  15. 0 159
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/SpecialRegionRecallStrategy.java
  16. 0 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java
  17. 0 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java
  18. 0 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java
  19. 0 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java
  20. 0 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractVideoRecallStrategy.java
  21. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithLevelRecallStrategy.java
  22. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithLevelScoreRecallStrategy.java
  23. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithScoreRecallStrategy.java
  24. 3 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithLevelRecallStrategy.java
  25. 2 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithLevelScoreRecallStrategy.java
  26. 2 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithScoreRecallStrategy.java
  27. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Region24HRecallStrategy.java
  28. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionHRecallStrategy.java
  29. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HDupRecallStrategy.java
  30. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HRecallStrategy.java
  31. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative48HDupRecallStrategy.java
  32. 1 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative48HRecallStrategy.java
  33. 3 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ReturnVideoRecallStrategy.java
  34. 4 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/SimHotVideoRecallStrategy.java

+ 10 - 9
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java

@@ -54,14 +54,15 @@ public final class Recommend {
       "\021 \001(\t\022\022\n\nscene_type\030\022 \001(\005\022\032\n\022recommend_t" +
       "race_id\030\023 \001(\t\"P\n\031HomepageRecommendRespon" +
       "se\022\027\n\006result\030\001 \001(\0132\007.Result\022\032\n\005video\030\002 \003" +
-      "(\0132\013.VideoProto\"{\n\nVideoProto\022\020\n\010video_i" +
-      "d\030\001 \001(\003\022\021\n\trov_score\030\002 \001(\001\022\021\n\tpush_from\030" +
-      "\003 \001(\t\022\017\n\007ab_code\030\004 \001(\t\022\022\n\nsort_score\030\005 \001" +
-      "(\001\022\020\n\010position\030\006 \001(\0052^\n\020RecommendService" +
-      "\022J\n\021HomepageRecommend\022\031.HomepageRecommen" +
-      "dRequest\032\032.HomepageRecommendResponseB7\n0" +
-      "com.tzld.piaoquan.recommend.server.gen.r" +
-      "ecommendP\001\210\001\001b\006proto3"
+      "(\0132\013.VideoProto\"\265\001\n\nVideoProto\022\020\n\010video_" +
+      "id\030\001 \001(\003\022\021\n\trov_score\030\002 \001(\001\022\021\n\tpush_from" +
+      "\030\003 \001(\t\022\017\n\007ab_code\030\004 \001(\t\022\022\n\nsort_score\030\005 " +
+      "\001(\001\022\020\n\010position\030\006 \001(\005\022\021\n\tflow_pool\030\007 \001(\t" +
+      "\022\027\n\017is_in_flow_pool\030\010 \001(\005\022\014\n\004rand\030\t \001(\0012" +
+      "^\n\020RecommendService\022J\n\021HomepageRecommend" +
+      "\022\031.HomepageRecommendRequest\032\032.HomepageRe" +
+      "commendResponseB7\n0com.tzld.piaoquan.rec" +
+      "ommend.server.gen.recommendP\001\210\001\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -86,7 +87,7 @@ public final class Recommend {
     internal_static_VideoProto_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_VideoProto_descriptor,
-        new java.lang.String[] { "VideoId", "RovScore", "PushFrom", "AbCode", "SortScore", "Position", });
+        new java.lang.String[] { "VideoId", "RovScore", "PushFrom", "AbCode", "SortScore", "Position", "FlowPool", "IsInFlowPool", "Rand", });
     com.google.protobuf.AnyProto.getDescriptor();
     com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor();
   }

+ 268 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoProto.java

@@ -18,6 +18,7 @@ private static final long serialVersionUID = 0L;
   private VideoProto() {
     pushFrom_ = "";
     abCode_ = "";
+    flowPool_ = "";
   }
 
   @java.lang.Override
@@ -82,6 +83,22 @@ private static final long serialVersionUID = 0L;
             position_ = input.readInt32();
             break;
           }
+          case 58: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            flowPool_ = s;
+            break;
+          }
+          case 64: {
+
+            isInFlowPool_ = input.readInt32();
+            break;
+          }
+          case 73: {
+
+            rand_ = input.readDouble();
+            break;
+          }
           default: {
             if (!parseUnknownField(
                 input, unknownFields, extensionRegistry, tag)) {
@@ -234,6 +251,66 @@ private static final long serialVersionUID = 0L;
     return position_;
   }
 
+  public static final int FLOW_POOL_FIELD_NUMBER = 7;
+  private volatile java.lang.Object flowPool_;
+  /**
+   * <code>string flow_pool = 7;</code>
+   * @return The flowPool.
+   */
+  @java.lang.Override
+  public java.lang.String getFlowPool() {
+    java.lang.Object ref = flowPool_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      flowPool_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string flow_pool = 7;</code>
+   * @return The bytes for flowPool.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getFlowPoolBytes() {
+    java.lang.Object ref = flowPool_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      flowPool_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int IS_IN_FLOW_POOL_FIELD_NUMBER = 8;
+  private int isInFlowPool_;
+  /**
+   * <code>int32 is_in_flow_pool = 8;</code>
+   * @return The isInFlowPool.
+   */
+  @java.lang.Override
+  public int getIsInFlowPool() {
+    return isInFlowPool_;
+  }
+
+  public static final int RAND_FIELD_NUMBER = 9;
+  private double rand_;
+  /**
+   * <code>double rand = 9;</code>
+   * @return The rand.
+   */
+  @java.lang.Override
+  public double getRand() {
+    return rand_;
+  }
+
   private byte memoizedIsInitialized = -1;
   @java.lang.Override
   public final boolean isInitialized() {
@@ -266,6 +343,15 @@ private static final long serialVersionUID = 0L;
     if (position_ != 0) {
       output.writeInt32(6, position_);
     }
+    if (!getFlowPoolBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 7, flowPool_);
+    }
+    if (isInFlowPool_ != 0) {
+      output.writeInt32(8, isInFlowPool_);
+    }
+    if (rand_ != 0D) {
+      output.writeDouble(9, rand_);
+    }
     unknownFields.writeTo(output);
   }
 
@@ -297,6 +383,17 @@ private static final long serialVersionUID = 0L;
       size += com.google.protobuf.CodedOutputStream
         .computeInt32Size(6, position_);
     }
+    if (!getFlowPoolBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, flowPool_);
+    }
+    if (isInFlowPool_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(8, isInFlowPool_);
+    }
+    if (rand_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(9, rand_);
+    }
     size += unknownFields.getSerializedSize();
     memoizedSize = size;
     return size;
@@ -326,6 +423,13 @@ private static final long serialVersionUID = 0L;
             other.getSortScore())) return false;
     if (getPosition()
         != other.getPosition()) return false;
+    if (!getFlowPool()
+        .equals(other.getFlowPool())) return false;
+    if (getIsInFlowPool()
+        != other.getIsInFlowPool()) return false;
+    if (java.lang.Double.doubleToLongBits(getRand())
+        != java.lang.Double.doubleToLongBits(
+            other.getRand())) return false;
     if (!unknownFields.equals(other.unknownFields)) return false;
     return true;
   }
@@ -352,6 +456,13 @@ private static final long serialVersionUID = 0L;
         java.lang.Double.doubleToLongBits(getSortScore()));
     hash = (37 * hash) + POSITION_FIELD_NUMBER;
     hash = (53 * hash) + getPosition();
+    hash = (37 * hash) + FLOW_POOL_FIELD_NUMBER;
+    hash = (53 * hash) + getFlowPool().hashCode();
+    hash = (37 * hash) + IS_IN_FLOW_POOL_FIELD_NUMBER;
+    hash = (53 * hash) + getIsInFlowPool();
+    hash = (37 * hash) + RAND_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getRand()));
     hash = (29 * hash) + unknownFields.hashCode();
     memoizedHashCode = hash;
     return hash;
@@ -497,6 +608,12 @@ private static final long serialVersionUID = 0L;
 
       position_ = 0;
 
+      flowPool_ = "";
+
+      isInFlowPool_ = 0;
+
+      rand_ = 0D;
+
       return this;
     }
 
@@ -529,6 +646,9 @@ private static final long serialVersionUID = 0L;
       result.abCode_ = abCode_;
       result.sortScore_ = sortScore_;
       result.position_ = position_;
+      result.flowPool_ = flowPool_;
+      result.isInFlowPool_ = isInFlowPool_;
+      result.rand_ = rand_;
       onBuilt();
       return result;
     }
@@ -597,6 +717,16 @@ private static final long serialVersionUID = 0L;
       if (other.getPosition() != 0) {
         setPosition(other.getPosition());
       }
+      if (!other.getFlowPool().isEmpty()) {
+        flowPool_ = other.flowPool_;
+        onChanged();
+      }
+      if (other.getIsInFlowPool() != 0) {
+        setIsInFlowPool(other.getIsInFlowPool());
+      }
+      if (other.getRand() != 0D) {
+        setRand(other.getRand());
+      }
       this.mergeUnknownFields(other.unknownFields);
       onChanged();
       return this;
@@ -901,6 +1031,144 @@ private static final long serialVersionUID = 0L;
       onChanged();
       return this;
     }
+
+    private java.lang.Object flowPool_ = "";
+    /**
+     * <code>string flow_pool = 7;</code>
+     * @return The flowPool.
+     */
+    public java.lang.String getFlowPool() {
+      java.lang.Object ref = flowPool_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        flowPool_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string flow_pool = 7;</code>
+     * @return The bytes for flowPool.
+     */
+    public com.google.protobuf.ByteString
+        getFlowPoolBytes() {
+      java.lang.Object ref = flowPool_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        flowPool_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string flow_pool = 7;</code>
+     * @param value The flowPool to set.
+     * @return This builder for chaining.
+     */
+    public Builder setFlowPool(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      flowPool_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string flow_pool = 7;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearFlowPool() {
+      
+      flowPool_ = getDefaultInstance().getFlowPool();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string flow_pool = 7;</code>
+     * @param value The bytes for flowPool to set.
+     * @return This builder for chaining.
+     */
+    public Builder setFlowPoolBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      flowPool_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int isInFlowPool_ ;
+    /**
+     * <code>int32 is_in_flow_pool = 8;</code>
+     * @return The isInFlowPool.
+     */
+    @java.lang.Override
+    public int getIsInFlowPool() {
+      return isInFlowPool_;
+    }
+    /**
+     * <code>int32 is_in_flow_pool = 8;</code>
+     * @param value The isInFlowPool to set.
+     * @return This builder for chaining.
+     */
+    public Builder setIsInFlowPool(int value) {
+      
+      isInFlowPool_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 is_in_flow_pool = 8;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearIsInFlowPool() {
+      
+      isInFlowPool_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private double rand_ ;
+    /**
+     * <code>double rand = 9;</code>
+     * @return The rand.
+     */
+    @java.lang.Override
+    public double getRand() {
+      return rand_;
+    }
+    /**
+     * <code>double rand = 9;</code>
+     * @param value The rand to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRand(double value) {
+      
+      rand_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double rand = 9;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRand() {
+      
+      rand_ = 0D;
+      onChanged();
+      return this;
+    }
     @java.lang.Override
     public final Builder setUnknownFields(
         final com.google.protobuf.UnknownFieldSet unknownFields) {

+ 24 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/VideoProtoOrBuilder.java

@@ -54,4 +54,28 @@ public interface VideoProtoOrBuilder extends
    * @return The position.
    */
   int getPosition();
+
+  /**
+   * <code>string flow_pool = 7;</code>
+   * @return The flowPool.
+   */
+  java.lang.String getFlowPool();
+  /**
+   * <code>string flow_pool = 7;</code>
+   * @return The bytes for flowPool.
+   */
+  com.google.protobuf.ByteString
+      getFlowPoolBytes();
+
+  /**
+   * <code>int32 is_in_flow_pool = 8;</code>
+   * @return The isInFlowPool.
+   */
+  int getIsInFlowPool();
+
+  /**
+   * <code>double rand = 9;</code>
+   * @return The rand.
+   */
+  double getRand();
 }

+ 4 - 0
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto

@@ -36,6 +36,7 @@ message HomepageRecommendResponse {
   repeated VideoProto video = 2;
 }
 
+// RecommendRovVideoDTO
 message VideoProto{
   int64 video_id = 1;
   double rov_score = 2;
@@ -43,6 +44,9 @@ message VideoProto{
   string ab_code = 4;
   double sort_score = 5;
   int32 position = 6;
+  string flow_pool = 7;
+  int32 is_in_flow_pool = 8;
+  double rand = 9;
 }
 
 service RecommendService {

+ 12 - 11
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/HomepageRecommendParam.java

@@ -12,16 +12,17 @@ import lombok.Setter;
 @Getter
 @Setter
 public class HomepageRecommendParam {
-    private int top_K;
+    private int topK;
     private double flowPoolP;
-    private String ab_code;
-    private String rule_key;
-    private String data_key;
-    private int expire_time;
-    private boolean no_op_flag;
-    private int old_video_index;
-    private String rule_key_30day;
-    private String shield_config;
-    private String flow_pool_abtest_group;
-    private String rank_key_prefix;
+    private String abCode;
+    private String ruleKey;
+    private String dataKey;
+    private String flowPoolAbtestGroup;
+    private String rankKeyPrefix;
+    private int appType;
+    private Long videoId;
+    private String cityCode;
+    private String provinceCode;
+    private String mid;
+    private int size;
 }

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/Video.java

@@ -9,10 +9,12 @@ import lombok.Data;
 public class Video {
     private long videoId;
     private double rovScore;
+    private double sortScore;
     private String pushFrom;
     private String abCode;
     private String flowPool;
     private String level;
     private String flowPoolAbtestGroup;
     private boolean inFlowPool;
+    private double rand;
 }

+ 221 - 162
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -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) {

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/flowpool/FlowPoolConstants.java

@@ -8,6 +8,7 @@ public class FlowPoolConstants {
     public static final String EXPERIMENTAL_FLOW_SET_LEVEL_SCORE = "experimental_flow_set_level_score";
 
     public static final String PUSH_FORM = "flow_pool";
+    public static final String QUICK_PUSH_FORM = "quick_flow_pool";
 
     public static final String KEY_WITH_LEVEL_FORMAT = "flow:pool:level:item:%s:%s";
     public static final String KEY_QUICK_WITH_LEVEL_FORMAT = "flow:pool:quick:item:%s:3";

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java

@@ -14,4 +14,5 @@ public class RankParam {
     private String rankKeyPrefix;
     private double flowPoolP;
     private String abCode;
+    private int appType;
 }

+ 111 - 62
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java

@@ -1,6 +1,9 @@
 package com.tzld.piaoquan.recommend.server.service.rank;
 
+import com.tzld.piaoquan.recommend.server.common.enums.AppTypeEnum;
 import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.flowpool.FlowPoolConstants;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.RandomUtils;
@@ -20,31 +23,27 @@ public class RankService {
 
     public RankResult rank(RankParam param) {
 
-        if (param.getRecallResult() == null
-                || (CollectionUtils.isEmpty(param.getRecallResult().getRovPoolRecall())
-                && CollectionUtils.isEmpty(param.getRecallResult().getFlowPoolRecall()))) {
+        if (param == null
+                || param.getRecallResult() == null
+                || CollectionUtils.isEmpty(param.getRecallResult().getData())) {
             return null;
         }
 
-        // rank rov recall
-        List<Video> rov_recall_rank = rovRecallRank(param);
-
-        // rank flow pool recall
-        List<Video> flow_recall_rank = param.getRecallResult().getFlowPoolRecall().stream()
-                .collect(Collectors.toList());
-        Collections.sort(flow_recall_rank, Comparator.comparingDouble(o -> -o.getRovScore()));
-
+        List<Video> rovRecallRank = mergeAndRankRovRecall(param);
+        List<Video> flowPoolRank = mergeAndRankFlowPoolRecall(param);
 
-        // TODO 重构
+        // TODO 重构 rov和流量池 融合排序
         //    去重原则:
         //        如果视频在ROV召回池topK,则保留ROV召回池,否则保留流量池
+        // 1 rov pool topK
         Set<Long> rovTopKVideoIds = new HashSet<>();
-        for (int i = 0; i < param.getTopK() && i < rov_recall_rank.size(); i++) {
-            rovTopKVideoIds.add(rov_recall_rank.get(i).getVideoId());
+        for (int i = 0; i < param.getTopK() && i < rovRecallRank.size(); i++) {
+            rovTopKVideoIds.add(rovRecallRank.get(i).getVideoId());
         }
 
+        // 2 flow pool 移除topK视频
         Set<Long> flowPoolVideoIds = new HashSet<>();
-        Iterator<Video> flowRecallRankIte = flow_recall_rank.iterator();
+        Iterator<Video> flowRecallRankIte = flowPoolRank.iterator();
         while (flowRecallRankIte.hasNext()) {
             Video data = flowRecallRankIte.next();
             if (rovTopKVideoIds.contains(data.getVideoId())) {
@@ -54,7 +53,8 @@ public class RankService {
             }
         }
 
-        Iterator<Video> rovRecallRankIte = rov_recall_rank.iterator();
+        // rov pool 移除flow中的视频
+        Iterator<Video> rovRecallRankIte = rovRecallRank.iterator();
         while (rovRecallRankIte.hasNext()) {
             Video data = rovRecallRankIte.next();
             if (flowPoolVideoIds.contains(data.getVideoId())) {
@@ -63,99 +63,148 @@ public class RankService {
         }
 
         // 融合排序
-        if (CollectionUtils.isEmpty(rov_recall_rank)) {
-            if (param.getSize() < flow_recall_rank.size()) {
-                return new RankResult(flow_recall_rank.subList(0, param.getSize()));
+        if (CollectionUtils.isEmpty(rovRecallRank)) {
+            if (param.getSize() < flowPoolRank.size()) {
+                return new RankResult(flowPoolRank.subList(0, param.getSize()));
             } else {
-                return new RankResult(flow_recall_rank);
+                return new RankResult(flowPoolRank);
             }
         }
 
-        List<Video> datas = new ArrayList<>();
-        for (int i = 0; i < param.getTopK() && i < rov_recall_rank.size(); i++) {
-            datas.add(rov_recall_rank.get(i));
-        }
-
-        double flowPoolP = param.getFlowPoolP();
-        if (param.getRecallResult().isQuickPool()) {
-            String quick_flow_pool_P = redisTemplate.opsForValue().get("flow:pool:quick:distribute:rate:3");
-            flowPoolP = NumberUtils.toDouble(quick_flow_pool_P, 0);
+        List<Video> result = new ArrayList<>();
+        for (int i = 0; i < param.getTopK() && i < rovRecallRank.size(); i++) {
+            result.add(rovRecallRank.get(i));
         }
 
+        double flowPoolP = getFlowPoolP(param);
         int flowPoolIndex = 0;
         int rovPoolIndex = param.getTopK() - 1;
 
         for (int i = 0; i < param.getSize() - param.getTopK(); i++) {
             double rand = RandomUtils.nextDouble(0, 1);
             if (rand < flowPoolP) {
-                if (flowPoolIndex < flow_recall_rank.size()) {
-                    datas.add(flow_recall_rank.get(flowPoolIndex++));
+                if (flowPoolIndex < flowPoolRank.size()) {
+                    result.add(flowPoolRank.get(flowPoolIndex++));
                 } else {
                     break;
                 }
             } else {
-                if (rovPoolIndex < rov_recall_rank.size()) {
-                    datas.add(rov_recall_rank.get(rovPoolIndex++));
+                if (rovPoolIndex < rovRecallRank.size()) {
+                    result.add(rovRecallRank.get(rovPoolIndex++));
                 } else {
                     break;
                 }
             }
         }
-        if (rovPoolIndex >= rov_recall_rank.size()) {
-            for (int i = flowPoolIndex; i < flow_recall_rank.size(); i++) {
-                datas.add(flow_recall_rank.get(i));
+        if (rovPoolIndex >= rovRecallRank.size()) {
+            for (int i = flowPoolIndex; i < flowPoolRank.size() && result.size() < param.getSize(); i++) {
+                result.add(flowPoolRank.get(i));
             }
         }
-        if (flowPoolIndex >= flow_recall_rank.size()) {
-            for (int i = rovPoolIndex; i < rov_recall_rank.size(); i++) {
-                datas.add(rov_recall_rank.get(i));
+        if (flowPoolIndex >= flowPoolRank.size()) {
+            for (int i = rovPoolIndex; i < rovRecallRank.size() && result.size() < param.getSize(); i++) {
+                result.add(rovRecallRank.get(i));
             }
         }
-        return new RankResult(datas);
+        return new RankResult(result);
     }
 
-    private List<Video> rovRecallRank(RankParam param) {
+    private List<Video> mergeAndRankRovRecall(RankParam param) {
+        List<Video> rovRecallRank = new ArrayList<>();
+        rovRecallRank.addAll(extractAndSort(param, RegionHRecallStrategy.PUSH_FORM));
+        rovRecallRank.addAll(extractAndSort(param, Region24HRecallStrategy.PUSH_FORM));
+        rovRecallRank.addAll(extractAndSort(param, RegionRelative24HRecallStrategy.PUSH_FORM));
+        rovRecallRank.addAll(extractAndSort(param, RegionRelative24HDupRecallStrategy.PUSH_FORM));
+        // TODO 为什么sim recall 和 return recall 不去重
+        rovRecallRank.addAll(extractAndSort(param, SimHotVideoRecallStrategy.PUSH_FORM));
+        rovRecallRank.addAll(extractAndSort(param, ReturnVideoRecallStrategy.PUSH_FORM));
+
+        // 去重
+        if (CollectionUtils.isNotEmpty(rovRecallRank)) {
+            Set<Long> videoIds = new HashSet<>();
+            Iterator<Video> ite = rovRecallRank.iterator();
+            while (ite.hasNext()) {
+                Video v = ite.next();
+                if (videoIds.contains(v.getVideoId())) {
+                    ite.remove();
+                    continue;
+                }
+                videoIds.add(v.getVideoId());
+            }
+        }
+
+        // 排序实验
         if (param.getAbCode().equals("60054")
                 || param.getAbCode().equals("60068")
                 || param.getAbCode().equals("60081")
                 || param.getAbCode().equals("60084")) {
 
-            List<String> videoIdKeys = param.getRecallResult().getRovPoolRecall().stream()
+            List<String> videoIdKeys = rovRecallRank.stream()
                     .map(t -> param.getRankKeyPrefix() + t.getVideoId())
                     .collect(Collectors.toList());
-            List<Video> rov_recall_rank = param.getRecallResult().getRovPoolRecall().stream()
-                    .collect(Collectors.toList());
             List<String> video_scores = redisTemplate.opsForValue().multiGet(videoIdKeys);
             if (CollectionUtils.isNotEmpty(video_scores)
-                    && video_scores.size() == rov_recall_rank.size()) {
+                    && video_scores.size() == rovRecallRank.size()) {
                 for (int i = 0; i < video_scores.size(); i++) {
-                    rov_recall_rank.get(i).setRovScore(NumberUtils.toDouble(video_scores.get(i), 0.0));
+                    rovRecallRank.get(i).setSortScore(NumberUtils.toDouble(video_scores.get(i), 0.0));
                 }
-                Collections.sort(rov_recall_rank, Comparator.comparingDouble(o -> -o.getRovScore()));
+                Collections.sort(rovRecallRank, Comparator.comparingDouble(o -> -o.getSortScore()));
+            }
+        }
+        return rovRecallRank;
+    }
+
+    private List<Video> mergeAndRankFlowPoolRecall(RankParam param) {
+        if (param.getAppType() == AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode()
+                || param.getAppType() == AppTypeEnum.ZUI_JING_QI.getCode()) {
+            if (param.getAbCode().equals("60054")
+                    || param.getAbCode().equals("60068")
+                    || param.getAbCode().equals("60081")
+                    || param.getAbCode().equals("60084")) {
+                return extractAndSort(param, FlowPoolConstants.QUICK_PUSH_FORM);
+            } else {
+                return Collections.emptyList();
             }
-            return rov_recall_rank;
         } else {
-            List<Video> rov_recall_rank = new ArrayList<>();
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, RegionHRecallStrategy.PUSH_FORM));
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, Region24HRecallStrategy.PUSH_FORM));
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, RegionRelative24HRecallStrategy.PUSH_FORM));
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, RegionRelative24HDupRecallStrategy.PUSH_FORM));
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, RegionRelative48HRecallStrategy.PUSH_FORM));
-            rov_recall_rank.addAll(extractRovPoolAndSort(param, RegionRelative48HDupRecallStrategy.PUSH_FORM));
-            return rov_recall_rank;
+            List<Video> quickFlowPoolVideos = extractAndSort(param, FlowPoolConstants.QUICK_PUSH_FORM);
+            if (CollectionUtils.isNotEmpty(quickFlowPoolVideos)) {
+                return quickFlowPoolVideos;
+            } else {
+                return extractAndSort(param, FlowPoolConstants.PUSH_FORM);
+            }
         }
     }
 
-    private List<Video> extractRovPoolAndSort(RankParam param, String pushForm) {
+    private List<Video> extractAndSort(RankParam param, String pushForm) {
         if (param == null
                 || param.getRecallResult() == null
-                || CollectionUtils.isEmpty(param.getRecallResult().getRovPoolRecall())) {
+                || CollectionUtils.isEmpty(param.getRecallResult().getData())) {
             return Collections.emptyList();
         }
-        return param.getRecallResult().getRovPoolRecall().stream()
-                .filter(o -> o.getPushFrom().equals(pushForm))
-                .sorted(Comparator.comparingDouble(o -> -o.getRovScore()))
-                .collect(Collectors.toList());
+        RecallResult.RecallData data = param.getRecallResult().getData().stream()
+                .filter(d -> d.getPushForm().equals(pushForm))
+                .findFirst().get();
+        if (data != null) {
+            List<Video> result = data.getVideos();
+            Collections.sort(result, Comparator.comparingDouble(o -> -o.getRovScore()));
+            return result;
+        }
+        return Collections.emptyList();
+    }
+
+    private double getFlowPoolP(RankParam param) {
+        if (param.getAppType() == AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode()
+                || param.getAppType() == AppTypeEnum.ZUI_JING_QI.getCode()) {
+            return param.getFlowPoolP();
+        } else {
+            List<Video> quickFlowPoolVideos = extractAndSort(param, FlowPoolConstants.QUICK_PUSH_FORM);
+            if (CollectionUtils.isNotEmpty(quickFlowPoolVideos)) {
+                String quick_flow_pool_P = redisTemplate.opsForValue().get("flow:pool:quick:distribute:rate:3");
+                return NumberUtils.toDouble(quick_flow_pool_P, 0);
+            } else {
+                return param.getFlowPoolP();
+            }
+        }
     }
 
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java

@@ -16,6 +16,6 @@ public class RecallParam {
     private String abCode;
     private int size;
     private String flowPoolAbtestGroup;
-    private String videoId;
+    private Long videoId;
 
 }

+ 14 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallResult.java

@@ -1,7 +1,9 @@
 package com.tzld.piaoquan.recommend.server.service.recall;
 
 import com.tzld.piaoquan.recommend.server.model.Video;
+import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.util.List;
 
@@ -9,8 +11,17 @@ import java.util.List;
  * @author dyp
  */
 @Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class RecallResult {
-    private List<Video> rovPoolRecall;
-    private List<Video> flowPoolRecall;
-    private boolean quickPool;
+    private List<RecallData> data;
+
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class RecallData {
+        private String pushForm;
+        private List<Video> videos;
+    }
+
 }

+ 127 - 98
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java

@@ -1,10 +1,13 @@
 package com.tzld.piaoquan.recommend.server.service.recall;
 
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.tzld.piaoquan.recommend.server.common.enums.AppTypeEnum;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.service.ThreadPoolFactory;
+import com.tzld.piaoquan.recommend.server.service.flowpool.FlowPoolConstants;
 import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -27,6 +30,8 @@ public class RecallService implements ApplicationContextAware {
     private final Map<String, RecallStrategy> strategyMap = new HashMap<>();
     private ApplicationContext applicationContext;
     private ExecutorService pool = ThreadPoolFactory.recallPool();
+    @ApolloJsonValue("city_code")
+    private Set<String> cityCodes;
 
     @PostConstruct
     public void init() {
@@ -40,12 +45,12 @@ public class RecallService implements ApplicationContextAware {
     public RecallResult recall(RecallParam param) {
         List<RecallStrategy> strategies = getRecallStrategy(param);
         CountDownLatch cdl = new CountDownLatch(strategies.size());
-        List<Future<List<Video>>> recallResultFutures = new ArrayList<>(strategies.size());
+        List<Future<RecallResult.RecallData>> recallResultFutures = new ArrayList<>(strategies.size());
         for (RecallStrategy strategy : strategies) {
-            Future<List<Video>> future = pool.submit(() -> {
+            Future<RecallResult.RecallData> future = pool.submit(() -> {
                 List<Video> result = strategy.recall(param);
                 cdl.countDown();
-                return result;
+                return new RecallResult.RecallData(strategy.pushFrom(), result);
             });
             recallResultFutures.add(future);
         }
@@ -56,116 +61,34 @@ public class RecallService implements ApplicationContextAware {
             return null;
         }
 
-
-        // TODO 重构
-        // merge
-        return merge(recallResultFutures, param);
-    }
-
-    private RecallResult merge(List<Future<List<Video>>> recallResultFutures, RecallParam param) {
-        List<List<Video>> results = new ArrayList<>();
-        for (Future<List<Video>> f : recallResultFutures) {
+        List<RecallResult.RecallData> results = new ArrayList<>();
+        for (Future<RecallResult.RecallData> f : recallResultFutures) {
             try {
                 results.add(f.get());
             } catch (Exception e) {
                 log.error("future get error ", e);
-                results.add(Collections.emptyList());
-            }
-        }
-
-        // TODO 重构 merge sim recall and return recall
-        Set<Long> videoIds = new HashSet<>();
-        List<Video> datas = new ArrayList<>();
-        if (param.getAbCode().equals("60054")
-                || param.getAbCode().equals("60068")
-                || param.getAbCode().equals("60081")
-                || param.getAbCode().equals("60084")) {
-            if (results.size() >= 2) {
-                List<Video> region_recall = results.get(0);
-                if (CollectionUtils.isNotEmpty(region_recall)) {
-                    for (Video data : region_recall) {
-                        if (!videoIds.contains(data.getVideoId())) {
-                            datas.add(data);
-                            videoIds.add(data.getVideoId());
-                        }
-                    }
-                }
-                List<Video> simRecall = null;
-                List<Video> returnRecall = null;
-                if (param.getAppType() == 18 || param.getAppType() == 19) {
-                    simRecall = results.get(1);
-                } else {
-                    if (results.size() >= 4) {
-                        simRecall = results.get(3);
-                    }
-                    if (results.size() >= 5 && !param.getAbCode().equals("60054")) {
-                        returnRecall = results.get(4);
-                    }
-                }
-
-                if (simRecall != null && CollectionUtils.isNotEmpty(simRecall)) {
-                    for (Video data : simRecall) {
-                        if (!videoIds.contains(data.getVideoId())) {
-                            datas.add(data);
-                            videoIds.add(data.getVideoId());
-                        }
-                    }
-                }
-
-                if (returnRecall != null && CollectionUtils.isNotEmpty(returnRecall)) {
-                    for (Video data : returnRecall) {
-                        if (!videoIds.contains(data.getVideoId())) {
-                            datas.add(data);
-                            videoIds.add(data.getVideoId());
-                        }
-                    }
-                }
-                if (CollectionUtils.isNotEmpty(datas)) {
-                    results.set(0, datas);
-                }
             }
         }
 
-
-        RecallResult result = new RecallResult();
-        if (param.getAppType() == 18 || param.getAppType() == 19) {
-            // TODO 可能没有这个code
-            if (param.getAbCode().equals("30001")
-                    || param.getAbCode().equals("30002")
-                    || param.getAbCode().equals("80001")) {
-                result.setRovPoolRecall(results.get(0));
-                result.setFlowPoolRecall(results.get(1));
-            } else {
-                result.setRovPoolRecall(results.get(0));
-            }
-        } else {
-            if (CollectionUtils.isNotEmpty(results.get(1))) {
-                result.setQuickPool(true);
-                result.setRovPoolRecall(results.get(0));
-                result.setFlowPoolRecall(results.get(1));
-
-            } else {
-                result.setRovPoolRecall(results.get(0));
-                result.setFlowPoolRecall(results.get(2));
-            }
-        }
-        return result;
+        return new RecallResult(results);
     }
 
     private List<RecallStrategy> getRecallStrategy(RecallParam param) {
         List<RecallStrategy> strategies = new ArrayList<>();
-        if (param.getAppType() == 18 || param.getAppType() == 19) {
-            strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
-        } else if (param.getFlowPoolAbtestGroup().equals("experimental_flow_set_level")) {
-            strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
+
+        if (param.getAppType() == AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode()
+                || param.getAppType() == AppTypeEnum.ZUI_JING_QI.getCode()) {
+            strategies.addAll(getRegionRecallStrategy(param));
+        } else if (param.getFlowPoolAbtestGroup().equals(FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL)) {
+            strategies.addAll(getRegionRecallStrategy(param));
             strategies.add(strategyMap.get(QuickFlowPoolWithLevelRecallStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(FlowPoolWithLevelRecallStrategy.class.getSimpleName()));
-        } else if (param.getFlowPoolAbtestGroup().equals("experimental_flow_set_level_score")) {
-            strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
+        } else if (param.getFlowPoolAbtestGroup().equals(FlowPoolConstants.EXPERIMENTAL_FLOW_SET_LEVEL_SCORE)) {
+            strategies.addAll(getRegionRecallStrategy(param));
             strategies.add(strategyMap.get(QuickFlowPoolWithLevelScoreRecallStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(FlowPoolWithLevelScoreRecallStrategy.class.getSimpleName()));
         } else {
-            strategies.add(strategyMap.get(SpecialRegionRecallStrategy.class.getSimpleName()));
+            strategies.addAll(getRegionRecallStrategy(param));
             strategies.add(strategyMap.get(QuickFlowPoolWithScoreRecallStrategy.class.getSimpleName()));
             strategies.add(strategyMap.get(FlowPoolWithScoreRecallStrategy.class.getSimpleName()));
         }
@@ -182,6 +105,112 @@ public class RecallService implements ApplicationContextAware {
         return strategies;
     }
 
+    private List<RecallStrategy> getRegionRecallStrategy(RecallParam param) {
+        String provinceCode = StringUtils.isNotBlank(param.getProvinceCode())
+                ? param.getProvinceCode()
+                : "-1";
+        String cityCode = StringUtils.isNotBlank(param.getCityCode())
+                ? param.getCityCode()
+                : "-1";
+        String regionCode = cityCodes.contains(cityCode) ? cityCode : provinceCode;
+
+        List<RecallStrategy> strategies = new ArrayList<>();
+        if (regionCode.equals("-1")) {
+            strategies.add(strategyMap.get(RegionRelative24HRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(RegionRelative24HDupRecallStrategy.class.getSimpleName()));
+        } else {
+            strategies.add(strategyMap.get(RegionHRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(Region24HRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(RegionRelative24HRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(RegionRelative24HDupRecallStrategy.class.getSimpleName()));
+        }
+
+        return strategies;
+    }
+
+//    private RecallResult merge(List<Future<Pair<String, List<Video>>>> recallResultFutures, RecallParam param) {
+//
+//        // TODO 重构 merge sim recall and return recall
+//        Set<Long> videoIds = new HashSet<>();
+//        List<Video> datas = new ArrayList<>();
+//        if (param.getAbCode().equals("60054")
+//                || param.getAbCode().equals("60068")
+//                || param.getAbCode().equals("60081")
+//                || param.getAbCode().equals("60084")) {
+//            if (results.size() >= 2) {
+//                List<Video> region_recall = results.get(0);
+//                if (CollectionUtils.isNotEmpty(region_recall)) {
+//                    for (Video data : region_recall) {
+//                        if (!videoIds.contains(data.getVideoId())) {
+//                            datas.add(data);
+//                            videoIds.add(data.getVideoId());
+//                        }
+//                    }
+//                }
+//                List<Video> simRecall = null;
+//                List<Video> returnRecall = null;
+//                if (param.getAppType() == AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode()
+//                        || param.getAppType() == AppTypeEnum.ZUI_JING_QI.getCode()) {
+//                    simRecall = results.get(1);
+//                } else {
+//                    if (results.size() >= 4) {
+//                        simRecall = results.get(3);
+//                    }
+//                    if (results.size() >= 5 && !param.getAbCode().equals("60054")) {
+//                        returnRecall = results.get(4);
+//                    }
+//                }
+//
+//                if (simRecall != null && CollectionUtils.isNotEmpty(simRecall)) {
+//                    for (Video data : simRecall) {
+//                        if (!videoIds.contains(data.getVideoId())) {
+//                            datas.add(data);
+//                            videoIds.add(data.getVideoId());
+//                        }
+//                    }
+//                }
+//
+//                if (returnRecall != null && CollectionUtils.isNotEmpty(returnRecall)) {
+//                    for (Video data : returnRecall) {
+//                        if (!videoIds.contains(data.getVideoId())) {
+//                            datas.add(data);
+//                            videoIds.add(data.getVideoId());
+//                        }
+//                    }
+//                }
+//                if (CollectionUtils.isNotEmpty(datas)) {
+//                    results.set(0, datas);
+//                }
+//            }
+//        }
+//
+//
+//        RecallResult result = new RecallResult();
+//        if (param.getAppType() == AppTypeEnum.LAO_HAO_KAN_VIDEO.getCode()
+//                || param.getAppType() == AppTypeEnum.ZUI_JING_QI.getCode()) {
+//            // TODO 可能没有这个code
+//            if (param.getAbCode().equals("30001")
+//                    || param.getAbCode().equals("30002")
+//                    || param.getAbCode().equals("80001")) {
+//                result.setRovPoolRecall(results.get(0));
+//                result.setFlowPoolRecall(results.get(1));
+//            } else {
+//                result.setRovPoolRecall(results.get(0));
+//            }
+//        } else {
+//            if (CollectionUtils.isNotEmpty(results.get(1))) {
+//                result.setQuickPool(true);
+//                result.setRovPoolRecall(results.get(0));
+//                result.setFlowPoolRecall(results.get(1));
+//
+//            } else {
+//                result.setRovPoolRecall(results.get(0));
+//                result.setFlowPoolRecall(results.get(2));
+//            }
+//        }
+//        return result;
+//    }
+
     @Override
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
         this.applicationContext = applicationContext;

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallStrategy.java

@@ -9,4 +9,6 @@ import java.util.List;
  */
 public interface RecallStrategy {
     List<Video> recall(RecallParam param);
+
+    String pushFrom();
 }

+ 0 - 159
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/SpecialRegionRecallStrategy.java

@@ -1,159 +0,0 @@
-package com.tzld.piaoquan.recommend.server.service.recall;
-
-import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
-import com.tzld.piaoquan.recommend.server.model.Video;
-import com.tzld.piaoquan.recommend.server.service.ThreadPoolFactory;
-import com.tzld.piaoquan.recommend.server.service.recall.strategy.Region24HRecallStrategy;
-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 lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-import java.util.*;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author dyp
- */
-@Service
-@Slf4j
-public class SpecialRegionRecallStrategy implements ApplicationContextAware, RecallStrategy {
-
-    private final Map<String, RecallStrategy> strategyMap = new HashMap<>();
-
-    @Autowired
-    private RedisTemplate<String, String> redisTemplate;
-
-    private ApplicationContext applicationContext;
-
-    @ApolloJsonValue("city_code")
-    private Set<String> cityCodes;
-
-    private ExecutorService pool = ThreadPoolFactory.specialRegionPool();
-
-    @PostConstruct
-    public void init() {
-
-        Map<String, RecallStrategy> type = applicationContext.getBeansOfType(RecallStrategy.class);
-        for (Map.Entry<String, RecallStrategy> entry : type.entrySet()) {
-            RecallStrategy value = entry.getValue();
-            strategyMap.put(value.getClass().getSimpleName(), value);
-        }
-
-    }
-
-    public List<Video> recall(RecallParam param) {
-
-        // 1. region recall
-        String provinceCode = StringUtils.isNotBlank(param.getProvinceCode())
-                ? param.getProvinceCode()
-                : "-1";
-        String cityCode = StringUtils.isNotBlank(param.getCityCode())
-                ? param.getCityCode()
-                : "-1";
-        String regionCode;
-        if (cityCodes.contains(cityCode)) {
-            regionCode = cityCode;
-        } else {
-            regionCode = provinceCode;
-        }
-
-        List<RecallStrategy> strategies = new ArrayList<>();
-        if (regionCode.equals("-1")) {
-            strategies.add(strategyMap.get(RegionRelative24HRecallStrategy.class.getSimpleName()));
-            strategies.add(strategyMap.get(RegionRelative24HDupRecallStrategy.class.getSimpleName()));
-        } else {
-            strategies.add(strategyMap.get(RegionHRecallStrategy.class.getSimpleName()));
-            strategies.add(strategyMap.get(Region24HRecallStrategy.class.getSimpleName()));
-            strategies.add(strategyMap.get(RegionRelative24HRecallStrategy.class.getSimpleName()));
-            strategies.add(strategyMap.get(RegionRelative24HDupRecallStrategy.class.getSimpleName()));
-        }
-
-        // execute
-        CountDownLatch cdl = new CountDownLatch(strategies.size());
-        List<Future<List<Video>>> recallResultFutures = new ArrayList<>(strategies.size());
-        for (RecallStrategy strategy : strategies) {
-            Future<List<Video>> future = pool.submit(() -> {
-                List<Video> result = strategy.recall(param);
-                cdl.countDown();
-                return result;
-            });
-            recallResultFutures.add(future);
-        }
-        try {
-            cdl.await(3000, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            log.error("rov_pool_recall_with_region recall error", e);
-            return null;
-        }
-
-        // TODO 理解业务后重构,可以先召回 再过滤
-        // 2. 去重
-        Set<Long> videoIds = new HashSet<>();
-        List<Video> results = new ArrayList<>();
-        for (Future<List<Video>> f : recallResultFutures) {
-            if (results.size() >= param.getSize()) {
-                break;
-            }
-            try {
-                List<Video> datas = f.get();
-                if (CollectionUtils.isNotEmpty(f.get())) {
-                    for (Video data : datas) {
-                        if (!videoIds.contains(data.getVideoId())) {
-                            videoIds.add(data.getVideoId());
-                            results.add(data);
-                        }
-                        if (results.size() >= param.getSize()) {
-                            break;
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                // log
-            }
-        }
-
-
-        // 3. 对在流量池中存在的视频添加标记字段
-        for (Video data : results) {
-
-            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);
-                }
-            }
-        }
-
-        return results;
-    }
-
-    @Override
-    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-        this.applicationContext = applicationContext;
-    }
-}

+ 0 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelRecallStrategy.java

@@ -70,6 +70,4 @@ public abstract class AbstractFlowPoolWithLevelRecallStrategy implements RecallS
 
     abstract Pair<String, String> flowPoolKeyAndLevel(RecallParam param);
 
-    abstract String pushFrom();
-
 }

+ 0 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithLevelScoreRecallStrategy.java

@@ -75,6 +75,4 @@ public abstract class AbstractFlowPoolWithLevelScoreRecallStrategy implements Re
 
     abstract Pair<String, String> flowPoolKeyAndLevel(RecallParam param);
 
-    abstract String pushFrom();
-
 }

+ 0 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractFlowPoolWithScoreRecallStrategy.java

@@ -70,6 +70,4 @@ public abstract class AbstractFlowPoolWithScoreRecallStrategy implements RecallS
 
     abstract String flowPoolKey(RecallParam param);
 
-    abstract String pushFrom();
-
 }

+ 0 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractRegionRecallStrategy.java

@@ -163,6 +163,4 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
     abstract String poolKey(RecallParam param, String now_dt, int h);
 
     abstract String lastVideoKey(RecallParam param);
-
-    abstract String pushFrom();
 }

+ 0 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/AbstractVideoRecallStrategy.java

@@ -76,6 +76,4 @@ public abstract class AbstractVideoRecallStrategy implements RecallStrategy {
     }
 
     abstract String recallKey(RecallParam param);
-
-    abstract String pushFrom();
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithLevelRecallStrategy.java

@@ -94,7 +94,7 @@ public class FlowPoolWithLevelRecallStrategy extends AbstractFlowPoolWithLevelRe
     }
 
     @Override
-    String pushFrom() {
+    public String pushFrom() {
         return FlowPoolConstants.PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithLevelScoreRecallStrategy.java

@@ -94,7 +94,7 @@ public class FlowPoolWithLevelScoreRecallStrategy extends AbstractFlowPoolWithLe
     }
 
     @Override
-    String pushFrom() {
+    public  String pushFrom() {
         return FlowPoolConstants.PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/FlowPoolWithScoreRecallStrategy.java

@@ -18,7 +18,7 @@ public class FlowPoolWithScoreRecallStrategy extends AbstractFlowPoolWithScoreRe
     }
 
     @Override
-    String pushFrom() {
+    public String pushFrom() {
         return FlowPoolConstants.PUSH_FORM;
     }
 }

+ 3 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithLevelRecallStrategy.java

@@ -17,7 +17,8 @@ public class QuickFlowPoolWithLevelRecallStrategy extends AbstractFlowPoolWithLe
     }
 
     @Override
-    String pushFrom() {
-        return FlowPoolConstants.PUSH_FORM;
+    public String pushFrom() {
+        return FlowPoolConstants.QUICK_PUSH_FORM;
     }
+
 }

+ 2 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithLevelScoreRecallStrategy.java

@@ -19,7 +19,7 @@ public class QuickFlowPoolWithLevelScoreRecallStrategy extends AbstractFlowPoolW
     }
 
     @Override
-    String pushFrom() {
-        return FlowPoolConstants.PUSH_FORM;
+    public String pushFrom() {
+        return FlowPoolConstants.QUICK_PUSH_FORM;
     }
 }

+ 2 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/QuickFlowPoolWithScoreRecallStrategy.java

@@ -18,7 +18,7 @@ public class QuickFlowPoolWithScoreRecallStrategy extends AbstractFlowPoolWithSc
     }
 
     @Override
-    String pushFrom() {
-        return FlowPoolConstants.PUSH_FORM;
+    public String pushFrom() {
+        return FlowPoolConstants.QUICK_PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/Region24HRecallStrategy.java

@@ -29,7 +29,7 @@ public class Region24HRecallStrategy extends AbstractRegionRecallStrategy {
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionHRecallStrategy.java

@@ -29,7 +29,7 @@ public class RegionHRecallStrategy extends AbstractRegionRecallStrategy {
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HDupRecallStrategy.java

@@ -29,7 +29,7 @@ public class RegionRelative24HDupRecallStrategy extends AbstractRegionRecallStra
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative24HRecallStrategy.java

@@ -29,7 +29,7 @@ public class RegionRelative24HRecallStrategy extends AbstractRegionRecallStrateg
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative48HDupRecallStrategy.java

@@ -28,7 +28,7 @@ public class RegionRelative48HDupRecallStrategy extends AbstractRegionRecallStra
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 1 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/RegionRelative48HRecallStrategy.java

@@ -28,7 +28,7 @@ public class RegionRelative48HRecallStrategy extends AbstractRegionRecallStrateg
     }
 
     @Override
-    protected String pushFrom() {
+    public String pushFrom() {
         return PUSH_FORM;
     }
 }

+ 3 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/ReturnVideoRecallStrategy.java

@@ -6,6 +6,7 @@ import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
  * @author dyp
  */
 public class ReturnVideoRecallStrategy extends AbstractVideoRecallStrategy {
+    public static final String PUSH_FORM = "return_video_recall";
 
     @Override
     String recallKey(RecallParam param) {
@@ -13,7 +14,7 @@ public class ReturnVideoRecallStrategy extends AbstractVideoRecallStrategy {
     }
 
     @Override
-    protected String pushFrom() {
-        return "return_video_recall";
+    public String pushFrom() {
+        return PUSH_FORM;
     }
 }

+ 4 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/SimHotVideoRecallStrategy.java

@@ -7,13 +7,15 @@ import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
  */
 public class SimHotVideoRecallStrategy extends AbstractVideoRecallStrategy {
 
+    public static final String PUSH_FORM = "sim_hot_vid_recall";
+
     @Override
     String recallKey(RecallParam param) {
         return "sim_hot_" + param.getVideoId();
     }
 
     @Override
-    protected String pushFrom() {
-        return "sim_hot_vid_recall";
+    public String pushFrom() {
+        return PUSH_FORM;
     }
 }