浏览代码

feature refactor 20231219

sunmingze 1 年之前
父节点
当前提交
c100ab076c
共有 37 个文件被更改,包括 13440 次插入141 次删除
  1. 0 110
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/UserActionFeature.java
  2. 9 10
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/ItemFeature.java
  3. 13 13
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/RequestContext.java
  4. 1 1
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/RequestContextBytesFeature.java
  5. 180 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserActionFeature.java
  6. 1 1
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserBytesFeature.java
  7. 5 5
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserFeature.java
  8. 1 1
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/VideoBytesFeature.java
  9. 131 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/enums/VlogFeatureGroup.java
  10. 35 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/BytesGroup.java
  11. 192 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/BytesUtils.java
  12. 230 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/FeatureHash.java
  13. 66 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/LRBytesFeatureExtractorBase.java
  14. 156 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/VlogShareLRFeatureExtractor.java
  15. 819 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/BaseFeature.java
  16. 45 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/BaseFeatureOrBuilder.java
  17. 104 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/CtrSamples.java
  18. 897 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/FeatureGroup.java
  19. 51 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/FeatureGroupOrBuilder.java
  20. 1022 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/GroupedFeature.java
  21. 54 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/GroupedFeatureOrBuilder.java
  22. 1094 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRSamples.java
  23. 63 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRSamplesOrBuilder.java
  24. 834 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRWeight.java
  25. 39 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRWeightOrBuilder.java
  26. 1387 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/MachineInfoProto.java
  27. 121 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/MachineInfoProtoOrBuilder.java
  28. 122 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/Recommend.java
  29. 2494 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendRequest.java
  30. 215 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendRequestOrBuilder.java
  31. 966 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendResponse.java
  32. 48 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendResponseOrBuilder.java
  33. 316 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendService.java
  34. 367 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendServiceGrpc.java
  35. 1232 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/VideoProto.java
  36. 81 0
      recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/VideoProtoOrBuilder.java
  37. 49 0
      recommend-feature-client/src/main/proto/ctr_samples.proto

+ 0 - 110
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/UserActionFeature.java

@@ -1,110 +0,0 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
-
-import lombok.Data;
-
-import java.lang.Math;
-
-@Data
-public class UserActionFeature {
-    private double exp_cnt;
-    private double click_cnt;
-    private double share_cnt;
-    private double return_cnt;
-
-    private double ctr;
-    private double str;
-    private double rov;
-    private double ros;
-
-    private double ceilLog(Double key) {
-        return Math.ceil(Math.log(key));
-    }
-
-    private double bucketRatioFeature(Double key) {
-        long bucket = Math.round(Math.log(key * 100));
-        if( bucket > 100)
-            bucket = 100;
-        return (double) bucket;
-    }
-
-
-    public void setExp_cnt(Object key){
-        if(key == null ) {
-            this.exp_cnt = 0.0;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.exp_cnt = ceilLog(Double.valueOf(formateKey));
-        }
-    }
-
-    public void setClick_cnt(Object key){
-        if(key == null ){
-            this.click_cnt = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.click_cnt = ceilLog(Double.valueOf(formateKey));
-        }
-    }
-    public void setShare_cnt(Object key){
-        if(key == null ){
-            this.share_cnt = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.share_cnt = ceilLog(Double.valueOf(formateKey));
-        }
-    }
-    public void setReturn_cnt(Object key){
-        if(key == null ){
-            this.return_cnt = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.return_cnt = ceilLog(Double.valueOf(formateKey));
-        }
-    }
-
-    public void setCtr(Object key){
-        if(key == null ){
-            this.ctr = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.ctr = bucketRatioFeature(Double.valueOf(formateKey));
-        }
-    }
-
-    public void setStr(Object key){
-        if(key == null ){
-            this.str = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.str = bucketRatioFeature(Double.valueOf(formateKey));
-        }
-    }
-
-    public void setRov(Object key){
-        if(key == null ){
-            this.rov = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.rov = bucketRatioFeature(Double.valueOf(formateKey));
-        }
-    }
-
-    public void setRos(Object key){
-        if(key == null ){
-            this.ros = 0.0 ;
-        } else {
-            String formateKey = key.toString().replace("\\N", "-1");
-            this.ros = bucketRatioFeature(Double.valueOf(formateKey));
-        }
-    }
-
-
-
-
-
-
-
-
-
-
-}

+ 9 - 10
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/ItemFeature.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/ItemFeature.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -8,27 +8,26 @@ import lombok.NoArgsConstructor;
 @Getter
 @NoArgsConstructor
 public class ItemFeature {
-    private String videoId;
+    private String videoId = "0";
 
-    private String upId;
+    private String upId = "0";
 
-    private String tags;
+    private String tags = "0";
 
     /**
      * 有多个标题,暂时不会用到所以先不处理
      *
      * @since 2023-12-05
      */
-    private String title;
+    private String title = "0";
 
-    private String titleLength;
+    private String titleLength = "0";
 
-    private String playLength;
+    private String playLength = "0";
 
-    private String totalTime;
-
-    private String daysSinceUpload;
+    private String totalTime = "0";
 
+    private String daysSinceUpload = "0";
 
     // 当天统计量信息
     private UserActionFeature day1_cnt_features;

+ 13 - 13
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/RequestContext.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/RequestContext.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 
 import lombok.Getter;
@@ -10,20 +10,20 @@ public class RequestContext {
 
     private String request_id;
     // 机型等信息
-    private String apptype;
-    private String machineinfo_brand;
-    private String machineinfo_model;
-    private String machineinfo_platform;
-    private String machineinfo_sdkversion;
-    private String machineinfo_system;
-    private String machineinfo_wechatversion;
+    private String apptype = "-1";
+    private String machineinfo_brand = "-1";
+    private String machineinfo_model = "-1";
+    private String machineinfo_platform = "-1";
+    private String machineinfo_sdkversion = "-1";
+    private String machineinfo_system = "-1";
+    private String machineinfo_wechatversion = "-1";
 
     // 时间等信息
-    private String day;
-    private String week;
-    private String hour;
-    private String region;
-    private String city;
+    private String day = "-1";
+    private String week = "-1";
+    private String hour = "-1";
+    private String region = "-1";
+    private String city = "-1";
 
     public void setApptype(String apptype) {
         this.apptype = apptype;

+ 1 - 1
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/RequestContextBytesFeature.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/RequestContextBytesFeature.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 
 import lombok.Data;

+ 180 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserActionFeature.java

@@ -0,0 +1,180 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
+
+import lombok.Data;
+
+import java.lang.Math;
+
+@Data
+public class UserActionFeature {
+    private double exp_cnt = 0d;
+    private double click_cnt = 0d;
+    private double share_cnt = 0d;
+    private double return_cnt = 0d;
+
+    private double ctr = 0d;
+    private double str = 0d;
+    private double rov = 0d;
+    private double ros = 0d;
+
+    private double ceilLog(Double key) {
+        return Math.ceil(Math.log(key + 1));
+    }
+
+    private double bucketRatioFeature(Double key) {
+        long bucket = Math.round(Math.log((key + 1) * 50));
+        if (bucket > 50)
+            bucket = 50;
+        return (double) bucket;
+    }
+
+
+    public void setExp_cnt(Object key) {
+        if (key == null) {
+            this.exp_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.exp_cnt = ceilLog(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setClick_cnt(Object key) {
+        if (key == null) {
+            this.click_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.click_cnt = ceilLog(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setShare_cnt(Object key) {
+        if (key == null) {
+            this.share_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.share_cnt = ceilLog(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setReturn_cnt(Object key) {
+        if (key == null) {
+            this.return_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.return_cnt = ceilLog(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setCtr(Object key) {
+        if (key == null) {
+            this.ctr = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.ctr = bucketRatioFeature(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setStr(Object key) {
+        if (key == null) {
+            this.str = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.str = bucketRatioFeature(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setRov(Object key) {
+        if (key == null) {
+            this.rov = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.rov = bucketRatioFeature(Double.valueOf(formateKey));
+        }
+    }
+
+    public void setRos(Object key) {
+        if (key == null) {
+            this.ros = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "-1");
+            this.ros = bucketRatioFeature(Double.valueOf(formateKey));
+        }
+    }
+
+
+    public void setOriginExp_cnt(Object key) {
+        if (key == null) {
+            this.exp_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.exp_cnt = Double.valueOf(formateKey);
+        }
+    }
+
+    public void setOriginClick_cnt(Object key) {
+        if (key == null) {
+            this.click_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.click_cnt = Double.valueOf(formateKey);
+        }
+    }
+
+    public void setOriginShare_cnt(Object key) {
+        if (key == null) {
+            this.share_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.share_cnt = Double.valueOf(formateKey);
+        }
+    }
+
+    // redis中保存原始值  server段统一处理
+    public void setOriginReturn_cnt(Object key) {
+        if (key == null) {
+            this.return_cnt = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.return_cnt = Double.valueOf(formateKey);
+        }
+    }
+
+    public void setOriginCtr(Object key) {
+        if (key == null) {
+            this.ctr = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.ctr = Double.valueOf(formateKey);
+        }
+    }
+
+
+    public void setOriginStr(Object key) {
+        if (key == null) {
+            this.str = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.str = Double.valueOf(formateKey);
+        }
+    }
+
+    public void setOriginRov(Object key) {
+        if (key == null) {
+            this.rov = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.rov = Double.valueOf(formateKey);
+        }
+    }
+
+
+    public void setOriginRos(Object key) {
+        if (key == null) {
+            this.ros = 0.0;
+        } else {
+            String formateKey = key.toString().replace("\\N", "0");
+            this.ros = Double.valueOf(formateKey);
+        }
+    }
+
+
+}

+ 1 - 1
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/UserBytesFeature.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserBytesFeature.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 import lombok.Data;
 

+ 5 - 5
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/UserFeature.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/UserFeature.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -9,7 +9,7 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 public class UserFeature {
 
-    private String uid;
+    private String uid = "0";
     // 当天统计量信息
     private UserActionFeature day1_cnt_features;
     // 3天内统计量
@@ -19,9 +19,9 @@ public class UserFeature {
     // 3个月统计量
     private UserActionFeature month3_cnt_features;
     // 用户行为周期
-    private String user_cycle_bucket_7days;
-    private String user_cycle_bucket_30days;
-    private String user_share_bucket_30days;
+    private String user_cycle_bucket_7days = "0";
+    private String user_cycle_bucket_30days = "0";
+    private String user_share_bucket_30days = "0";
 
     public void setUid(String key) {
         this.uid = key;

+ 1 - 1
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/VideoBytesFeature.java → recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/base/VideoBytesFeature.java

@@ -1,4 +1,4 @@
-package com.tzld.piaoquan.recommend.feature.domain.video;
+package com.tzld.piaoquan.recommend.feature.domain.video.base;
 
 import lombok.Data;
 

+ 131 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/enums/VlogFeatureGroup.java

@@ -0,0 +1,131 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.enums;
+
+public enum VlogFeatureGroup {
+
+    // video
+    APPTYP,
+    VIDEOID,
+    MID,
+    UID,
+    MACHINEINFO_BRAND,
+    MACHINEINFO_MODEL,
+    MACHINEINFO_PLATFORM,
+    MACHINEINFO_SDKVERSION,
+    MACHINEINFO_SYSTEM,
+    MACHINEINFO_WECHATVERSION,
+    UP_ID,
+    TITLE_LEN,
+    PLAY_LEN,
+    TOTAL_TIME,
+    DAYS_SINCE_UPLOAD,
+    DAY,
+    WEEK,
+    HOUR,
+    REGION,
+    CITY,
+
+    USER_1DAY_EXP,
+    USER_1DAY_CLICK,
+    USER_1DAY_SHARE,
+    USER_1DAY_RETURN,
+    USER_1DAY_CTR,
+    USER_1DAY_STR,
+    USER_1DAY_ROV,
+    USER_1DAY_ROS,
+
+    USER_3DAY_EXP,
+    USER_3DAY_CLICK,
+    USER_3DAY_SHARE,
+    USER_3DAY_RETURN,
+    USER_3DAY_CTR,
+    USER_3DAY_STR,
+    USER_3DAY_ROV,
+    USER_3DAY_ROS,
+
+    USER_7DAY_EXP,
+    USER_7DAY_CLICK,
+    USER_7DAY_SHARE,
+    USER_7DAY_RETURN,
+    USER_7DAY_CTR,
+    USER_7DAY_STR,
+    USER_7DAY_ROV,
+    USER_7DAY_ROS,
+
+    USER_3MONTH_EXP,
+    USER_3MONTH_CLICK,
+    USER_3MONTH_SHARE,
+    USER_3MONTH_RETURN,
+    USER_3MONTH_CTR,
+    USER_3MONTH_STR,
+    USER_3MONTH_ROV,
+    USER_3MONTH_ROS,
+
+
+    ITEM_1DAY_EXP,
+    ITEM_1DAY_CLICK,
+    ITEM_1DAY_SHARE,
+    ITEM_1DAY_RETURN,
+    ITEM_1DAY_CTR,
+    ITEM_1DAY_STR,
+    ITEM_1DAY_ROV,
+    ITEM_1DAY_ROS,
+
+    ITEM_3DAY_EXP,
+    ITEM_3DAY_CLICK,
+    ITEM_3DAY_SHARE,
+    ITEM_3DAY_RETURN,
+    ITEM_3DAY_CTR,
+    ITEM_3DAY_STR,
+    ITEM_3DAY_ROV,
+    ITEM_3DAY_ROS,
+
+    ITEM_7DAY_EXP,
+    ITEM_7DAY_CLICK,
+    ITEM_7DAY_SHARE,
+    ITEM_7DAY_RETURN,
+    ITEM_7DAY_CTR,
+    ITEM_7DAY_STR,
+    ITEM_7DAY_ROV,
+    ITEM_7DAY_ROS,
+
+    ITEM_3MONTH_EXP,
+    ITEM_3MONTH_CLICK,
+    ITEM_3MONTH_SHARE,
+    ITEM_3MONTH_RETURN,
+    ITEM_3MONTH_CTR,
+    ITEM_3MONTH_STR,
+    ITEM_3MONTH_ROV,
+    ITEM_3MONTH_ROS,
+
+
+    USER_CYCLE_BUCKET_7DAY,
+    USER_CYCLE_BUCKET_30DAY,
+    USER_SHARE_BUCKET_30DAY,
+    ;
+
+
+    private final byte[] idBytes;
+    private final byte[] nameBytes;
+
+    VlogFeatureGroup() {
+        this.nameBytes = name().toLowerCase().getBytes();
+        this.idBytes = String.valueOf(ordinal()).getBytes();
+    }
+
+    public final int getId() {
+        return ordinal();
+    }
+
+    public final String getGroupName() {
+        return name().toLowerCase();
+    }
+
+    public final byte[] getGroupNameBytes() {
+        return getGroupName().getBytes();
+    }
+
+    public final byte[] getIdBytes() {
+        return idBytes;
+    }
+
+}

+ 35 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/BytesGroup.java

@@ -0,0 +1,35 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.feature;
+
+
+public class BytesGroup {
+    private int id;
+    private String name;
+    private byte[] nameBytes;
+    private byte[] buffer;
+
+    public BytesGroup(int id, String name, byte[] nameBytes) {
+        this.id = id;
+        this.name = name;
+        this.nameBytes = nameBytes;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public byte[] getNameBytes() {
+        return nameBytes;
+    }
+
+    public byte[] getBuffer() {
+        return buffer;
+    }
+
+    public void setBuffer(byte[] buffer) {
+        this.buffer = buffer;
+    }
+}

+ 192 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/BytesUtils.java

@@ -0,0 +1,192 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.feature;
+
+
+import com.tzld.piaoquan.recommend.feature.gen.recommend.BaseFeature;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extract features from user, item & context info. Returns 64-bit murmurhash of feature string as results.
+ */
+public class BytesUtils {
+    private static final byte[] SEPARATOR = "_".getBytes();
+    private static final byte[] FEATURE_SEPARATOR = "#".getBytes();
+    private static final int MAX_FEATURE_BYTES_LENGTH = 512;
+    private static final long SEED = 11L;
+    private BytesGroup[] groups;
+
+    /**
+     * 一个种特殊的List,在尝试写入null的时候回默默地扔掉.
+     * @param <E> List的元素类型.
+     */
+    public static class NullRejectingArrayList<E> extends ArrayList<E> {
+        public NullRejectingArrayList(int capacity) {
+            super(capacity);
+        }
+
+        public NullRejectingArrayList() {
+            super();
+        }
+
+        @Override
+        public boolean add(E e) {
+            return e != null && super.add(e);
+        }
+    }
+
+    public BytesUtils(BytesGroup[] groups) {
+        this.groups = groups;
+        for (BytesGroup g : groups) {
+            byte[] buffer = prepareBuffer(g.getName(), g.getNameBytes());
+            groups[g.getId()].setBuffer(buffer);
+        }
+    }
+
+    public byte[] prepareBuffer(String name, byte[] nameBytes) {
+
+        byte[] buffer = new byte[MAX_FEATURE_BYTES_LENGTH];
+        System.arraycopy(nameBytes, 0, buffer, 0, nameBytes.length);
+        System.arraycopy(FEATURE_SEPARATOR, 0, buffer, nameBytes.length, 1);
+        return buffer;
+    }
+
+    public BaseFeature baseFea(byte[] buffer, int length) {
+        long hash = FeatureHash.MurmurHash64(buffer, 0, length, SEED);
+
+        // debug中查看 String fea = new String(buffer, 0, length);
+        // 初始化protobuf并赋值
+        BaseFeature.Builder tmp = BaseFeature.newBuilder();
+        tmp.setIdentifier(hash);
+        return tmp.build();
+    }
+
+    public BaseFeature makeFea(int id, byte[] value) {
+        byte[] buffer = groups[id].getBuffer();
+        if (buffer == null || value == null) {
+            return null;
+        }
+
+        final int nameLength = groups[id].getNameBytes().length + 1;
+        final int length = nameLength + value.length;
+        System.arraycopy(value, 0, buffer, nameLength, value.length);
+        return baseFea(buffer, length);
+    }
+
+    public BaseFeature makeFea(int id, final byte[] p1, final byte[] p2) {
+        byte[] buffer = groups[id].getBuffer();
+        if (buffer == null || p1 == null || p2 == null) {
+            return null;
+        }
+
+        final int nameLength = groups[id].getNameBytes().length + 1;
+        final int length = nameLength + p1.length + 1 + p2.length;
+
+        System.arraycopy(p1, 0, buffer, nameLength, p1.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length, 1);
+        System.arraycopy(p2, 0, buffer, nameLength + p1.length + 1, p2.length);
+        return baseFea(buffer, length);
+    }
+
+    public BaseFeature makeFea(int id, final byte[] p1, final byte[] p2, final byte[] p3) {
+        byte[] buffer = groups[id].getBuffer();
+        if (buffer == null || p1 == null || p2 == null || p3 == null) {
+            return null;
+        }
+
+        final int nameLength = groups[id].getNameBytes().length + 1;
+        final int length = nameLength + p1.length + 1 + p2.length + 1 + p3.length;
+        System.arraycopy(p1, 0, buffer, nameLength, p1.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length, 1);
+        System.arraycopy(p2, 0, buffer, nameLength + p1.length + 1, p2.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length + 1 + p2.length, 1);
+        System.arraycopy(p3, 0, buffer, nameLength + p1.length + 1 + p2.length + 1, p3.length);
+
+        return baseFea(buffer, length);
+    }
+
+    public BaseFeature makeFea(int id, final byte[] p1, final byte[] p2, final byte[] p3, final byte[] p4) {
+        byte[] buffer = groups[id].getBuffer();
+        if (buffer == null || p1 == null || p2 == null || p3 == null || p4 == null) {
+            return null;
+        }
+
+        final int nameLength = groups[id].getNameBytes().length + 1;
+        final int length = nameLength + p1.length + 1 + p2.length + 1 + p3.length + 1 + p4.length;
+        System.arraycopy(p1, 0, buffer, nameLength, p1.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length, 1);
+        System.arraycopy(p2, 0, buffer, nameLength + p1.length + 1, p2.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length + 1 + p2.length, 1);
+        System.arraycopy(p3, 0, buffer, nameLength + p1.length + 1 + p2.length + 1, p3.length);
+        System.arraycopy(SEPARATOR, 0, buffer, nameLength + p1.length + 1 + p2.length + 1 + p3.length, 1);
+        System.arraycopy(p4, 0, buffer, nameLength + p1.length + 1 + p2.length + 1 + p3.length + 1, p4.length);
+
+        return baseFea(buffer, length);
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[][] list) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(list.length);
+        for (byte[] t: list) {
+            result.add(makeFea(id, t));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[][] left, byte[] right) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(left.length);
+        for (byte[] l: left) {
+            result.add(makeFea(id, l, right));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[][] left, byte[] right1, byte[] right2) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(left.length);
+        for (byte[] l: left) {
+            result.add(makeFea(id, l, right1, right2));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[][] left, byte[] right1, byte[] right2, byte[] right3) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(left.length);
+        for (byte[] l: left) {
+            result.add(makeFea(id, l, right1, right2, right3));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[] left, byte[][] right) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(right.length);
+        for (byte[] r : right) {
+            result.add(makeFea(id, left, r));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[] left1, byte[] left2, byte[][] right) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(right.length);
+        for (byte[] r : right) {
+            result.add(makeFea(id, left1, left2, r));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[] left1, byte[] left2, byte[] left3, byte[][] right) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(right.length);
+        for (byte[] r : right) {
+            result.add(makeFea(id, left1, left2, left3, r));
+        }
+        return result;
+    }
+
+    public List<BaseFeature> makeFea(int id, byte[][] left, byte[][] right) {
+        List<BaseFeature> result = new NullRejectingArrayList<BaseFeature>(left.length * right.length);
+        for (byte[] l: left) {
+            for (byte[] r: right) {
+                result.add(makeFea(id, l, r));
+            }
+        }
+        return result;
+    }
+}

+ 230 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/FeatureHash.java

@@ -0,0 +1,230 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.feature;
+
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+public class FeatureHash {
+    public static Charset CharSetUTF8 = Charset.forName("UTF-8");
+
+    public static long getUInt32(byte a, byte b, byte c, byte d) {
+        return (d << 24 | (c & 0xFF) << 16 | (b & 0xFF) << 8 | (a & 0xFF));
+    }
+
+    public static long hash64(byte[] data) {
+        return MurmurHash64A(ByteBuffer.wrap(data), 0, data.length, 11L);
+    }
+
+    public static long MurmurHash64A(ByteBuffer buffer, int from, int len, long seed) {
+        final long m = 0xc6a4a7935bd1e995L;
+        final int r = 47;
+
+        long h = (seed) ^ (len * m);
+        int longLength = len / 8;
+
+        for (int i = 0; i < longLength; ++i) {
+            final int bytePos = from + i * 8;
+            long k = buffer.getLong(bytePos);
+
+            k *= m;
+            k ^= k >> r;
+            k *= m;
+            h ^= k;
+            h *= m;
+        }
+
+        final int remainingPos = len & ~7;
+        switch (len % 8) {
+            case 7: h ^= (long)(buffer.get(remainingPos + 6) & 0xFF) << 48;
+            case 6: h ^= (long)(buffer.get(remainingPos + 5) & 0xFF) << 40;
+            case 5: h ^= (long)(buffer.get(remainingPos + 4) & 0xFF) << 32;
+            case 4: h ^= (long)(buffer.get(remainingPos + 3) & 0xFF) << 24;
+            case 3: h ^= (long)(buffer.get(remainingPos + 2) & 0xFF) << 16;
+            case 2: h ^= (long)(buffer.get(remainingPos + 1) & 0xFF) << 8;
+            case 1:
+                h ^= (long)(buffer.get(remainingPos) & 0xFF);
+                h *= m;
+        }
+
+        h ^= h >>> r;
+        h *= m;
+        h ^= h >>> r;
+        return h;
+    }
+
+    public static long MurmurHash32(byte data[], int len, long seed) {
+        long m = 0x5bd1e995L;
+        int r = 24;
+
+        long h = seed ^ len;
+
+        int offset = 0;
+        while (len >= 4) {
+            long k = getUInt32(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
+
+            k *= m;
+            k &= 0xFFFFFFFFL;
+            k ^= k >> r;
+            k *= m;
+            k &= 0xFFFFFFFFL;
+
+            h *= m;
+            h &= 0xFFFFFFFFL;
+            h ^= k;
+
+            offset += 4;
+            len -= 4;
+        }
+
+        // Handle the last few bytes of the input array
+        switch (len) {
+            case 3: h ^= data[offset + 2] << 16;
+            case 2: h ^= data[offset + 1] << 8;
+            case 1: h ^= data[offset];
+                h *= m;
+                h &= 0xFFFFFFFFL;
+        } ;
+
+        // Do a few final mixes of the hash to ensure the last few
+        // bytes are well-incorporated.
+
+        h ^= h >> 13;
+        h *= m;
+        h &= 0xFFFFFFFFL;
+        h ^= h >> 15;
+
+        return h;
+    }
+
+    // 64-bit hash for 32-bit platforms
+    public static long MurmurHash64(byte[] buffer, int start, int len, long seed) {
+        final long m = 0x5bd1e995L;
+        final int r = 24;
+        final int original = len;
+
+        long h1 = (seed) ^ len;
+        long h2 = (seed >> 32);
+
+        int offset = start;
+        while (len >= 8) {
+            long k1 = getUInt32(buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]);
+            // long k1 = buffer.getInt(offset);
+
+            k1 *= m; k1 &= 0xFFFFFFFFL; k1 ^= k1 >> r; k1 *= m; k1 &= 0xFFFFFFFFL;
+            h1 *= m; h1 &= 0xFFFFFFFFL; h1 ^= k1;
+            offset += 4;
+
+            long k2 = getUInt32(buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]);
+            // long k2 = buffer.getInt(offset);
+            k2 *= m; k2 &= 0xFFFFFFFFL; k2 ^= k2 >> r; k2 *= m; k2 &= 0xFFFFFFFFL;
+            h2 *= m; h2 &= 0xFFFFFFFFL; h2 ^= k2;
+
+            offset += 4;
+            len -= 8;
+        }
+
+        if (len >= 4) {
+            long k1 = getUInt32(buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3]);
+            // long k1 = buffer.getInt(offset);
+            k1 *= m; k1 &= 0xFFFFFFFFL; k1 ^= k1 >> r; k1 *= m; k1 &= 0xFFFFFFFFL;
+            h1 *= m; h1 &= 0xFFFFFFFFL; h1 ^= k1;
+            offset += 4;
+            len -= 4;
+        }
+
+        switch (len) {
+            case 3: h2 ^= (buffer[offset + 2] & 0xFF) << 16;
+            case 2: h2 ^= (buffer[offset + 1] & 0xFF) << 8;
+            case 1: h2 ^= (buffer[offset] & 0xFF);
+                h2 *= m;
+                h2 &= 0xFFFFFFFFL;
+        } ;
+
+        h1 ^= h2 >> 18;
+        h1 *= m; h1 &= 0xFFFFFFFFL;
+        h2 ^= h1 >> 22;
+        h2 *= m; h2 &= 0xFFFFFFFFL;
+        h1 ^= h2 >> 17;
+        h1 *= m; h1 &= 0xFFFFFFFFL;
+        h2 ^= h1 >> 19;
+        h2 *= m; h2 &= 0xFFFFFFFFL;
+
+        /*BigInteger ans = BigInteger.valueOf(h1).shiftLeft(32).or(BigInteger.valueOf(h2));
+        return ans.longValue();*/
+        //System.err.println("feature: " + new String(buffer, 0, original) + " length: " + original + " hash: " + (h1 << 32 | h2) + " daze");
+        return h1 << 32 | h2;
+    }
+
+    // 64-bit hash for 32-bit platforms
+    public static BigInteger MurmurHash64(byte data[], int len, long seed) {
+        long m = 0x5bd1e995L;
+        int r = 24;
+
+        long h1 = (seed) ^ len;
+        long h2 = (seed >> 32);
+
+        int offset = 0;
+        while (len >= 8) {
+            long k1 = getUInt32(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
+            k1 *= m; k1 &= 0xFFFFFFFFL; k1 ^= k1 >> r; k1 *= m; k1 &= 0xFFFFFFFFL;
+            h1 *= m; h1 &= 0xFFFFFFFFL; h1 ^= k1;
+
+            long k2 = getUInt32(data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7]);
+            k2 *= m; k2 &= 0xFFFFFFFFL; k2 ^= k2 >> r; k2 *= m; k2 &= 0xFFFFFFFFL;
+            h2 *= m; h2 &= 0xFFFFFFFFL; h2 ^= k2;
+
+            offset += 8;
+            len -= 8;
+        }
+
+        if (len >= 4) {
+            long k1 = getUInt32(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
+            k1 *= m; k1 &= 0xFFFFFFFFL; k1 ^= k1 >> r; k1 *= m; k1 &= 0xFFFFFFFFL;
+            h1 *= m; h1 &= 0xFFFFFFFFL; h1 ^= k1;
+            offset += 4;
+            len -= 4;
+        }
+
+        switch (len) {
+            case 3: h2 ^= (data[offset + 2] & 0xFF) << 16;
+            case 2: h2 ^= (data[offset + 1] & 0xFF) << 8;
+            case 1: h2 ^= (data[offset] & 0xFF);
+                h2 *= m;
+                h2 &= 0xFFFFFFFFL;
+        } ;
+
+        h1 ^= h2 >> 18;
+        h1 *= m; h1 &= 0xFFFFFFFFL;
+        h2 ^= h1 >> 22;
+        h2 *= m; h2 &= 0xFFFFFFFFL;
+        h1 ^= h2 >> 17;
+        h1 *= m; h1 &= 0xFFFFFFFFL;
+        h2 ^= h1 >> 19;
+        h2 *= m; h2 &= 0xFFFFFFFFL;
+
+        BigInteger ans = BigInteger.valueOf(h1).shiftLeft(32).or(BigInteger.valueOf(h2));
+        return ans;
+    }
+
+    public static String hash(String input) {
+        byte[] tt = input.getBytes(CharSetUTF8);
+        return MurmurHash64(tt, tt.length, 11L).toString();
+    }
+
+    public static Long hashToLong(String input) {
+        byte[] tt = input.getBytes(CharSetUTF8);
+        return MurmurHash64(tt, tt.length, 11L).longValue();
+    }
+
+    /** the constant 2^64 */
+    private static final BigInteger TWO_64 = BigInteger.ONE.shiftLeft(64);
+
+    public static String asUnsignedLongString(long l) {
+        BigInteger b = BigInteger.valueOf(l);
+        if (b.signum() < 0) {
+            b = b.add(TWO_64);
+        }
+        return b.toString();
+    }
+}

+ 66 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/LRBytesFeatureExtractorBase.java

@@ -0,0 +1,66 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.feature;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ListMultimap;
+
+import com.tzld.piaoquan.recommend.feature.domain.video.base.RequestContextBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.UserBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.VideoBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.enums.VlogFeatureGroup;
+import com.tzld.piaoquan.recommend.feature.gen.recommend.*;
+
+import java.util.List;
+
+
+public abstract class LRBytesFeatureExtractorBase {
+    private static final double DEFAULT_USER_CTR_GROUP = 10.0;
+    private static final double DEFAULT_ARTICLE_CTR_GROUP = 100.0;
+
+
+    private BytesUtils utils;
+    //Feature Group & Features
+    ListMultimap<FeatureGroup, BaseFeature> features = ArrayListMultimap.create();
+    int groupCount;
+
+
+    LRBytesFeatureExtractorBase() {
+        groupCount = VlogFeatureGroup.values().length;
+        BytesGroup[] groups = new BytesGroup[groupCount];
+        for (VlogFeatureGroup g: VlogFeatureGroup.values()) {
+            groups[g.ordinal()] = new BytesGroup(g.ordinal(),
+                    g.getGroupName(), g.getGroupNameBytes());
+        }
+        utils = new BytesUtils(groups);
+    }
+
+    private FeatureGroup makeGroup(VlogFeatureGroup group){
+        FeatureGroup.Builder g = FeatureGroup.newBuilder();
+        g.setType("1");
+        g.setName(group.getGroupName());
+        g.setId(group.ordinal());
+        return g.build();
+    };
+
+
+    void makeFea(VlogFeatureGroup group, byte[] value) {
+        FeatureGroup featureGroup = makeGroup(group);
+        BaseFeature feature = utils.makeFea(group.ordinal(), value);
+        features.put(featureGroup, feature);
+    }
+
+    void makeFea(VlogFeatureGroup group, byte[][] list) {
+        FeatureGroup g = makeGroup(group);
+        List<BaseFeature> featureList = utils.makeFea(group.ordinal(), list);
+        features.putAll(g, featureList);
+    }
+
+    public ListMultimap<FeatureGroup, BaseFeature> getFeatures() {
+        return features;
+    }
+
+    public abstract LRSamples single(UserBytesFeature userBytesFeature,
+                                     VideoBytesFeature videoBytesFeature,
+                                     RequestContextBytesFeature requestContextBytesFeature);
+
+
+}

+ 156 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/domain/video/feature/VlogShareLRFeatureExtractor.java

@@ -0,0 +1,156 @@
+package com.tzld.piaoquan.recommend.feature.domain.video.feature;
+
+import com.tzld.piaoquan.recommend.feature.domain.video.base.RequestContextBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.UserBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.base.VideoBytesFeature;
+import com.tzld.piaoquan.recommend.feature.domain.video.enums.VlogFeatureGroup;
+import com.tzld.piaoquan.recommend.feature.gen.recommend.*;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VlogShareLRFeatureExtractor extends LRBytesFeatureExtractorBase {
+
+    public VlogShareLRFeatureExtractor() {
+        super();
+    }
+
+    // TODO
+    // 补充待抽取的context feature
+    public void getContextFeatures(RequestContextBytesFeature requestContextBytes) {
+        makeFea(VlogFeatureGroup.MACHINEINFO_BRAND, requestContextBytes.getMachineinfo_brand());
+        makeFea(VlogFeatureGroup.MACHINEINFO_MODEL, requestContextBytes.getMachineinfo_model());
+        makeFea(VlogFeatureGroup.MACHINEINFO_PLATFORM, requestContextBytes.getMachineinfo_platform());
+        makeFea(VlogFeatureGroup.MACHINEINFO_SDKVERSION, requestContextBytes.getMachineinfo_sdkversion());
+        makeFea(VlogFeatureGroup.MACHINEINFO_SYSTEM, requestContextBytes.getMachineinfo_system());
+        makeFea(VlogFeatureGroup.MACHINEINFO_WECHATVERSION, requestContextBytes.getMachineinfo_brand());
+
+        makeFea(VlogFeatureGroup.DAY, requestContextBytes.getWeek());
+        makeFea(VlogFeatureGroup.WEEK, requestContextBytes.getWeek());
+        makeFea(VlogFeatureGroup.HOUR, requestContextBytes.getHour());
+
+    }
+
+    //TODO
+    public void getUserFeatures(UserBytesFeature user) {
+        makeFea(VlogFeatureGroup.USER_CYCLE_BUCKET_7DAY, user.getUser_cycle_bucket_7days());
+        makeFea(VlogFeatureGroup.USER_SHARE_BUCKET_30DAY, user.getUser_share_bucket_30days());
+        makeFea(VlogFeatureGroup.USER_SHARE_BUCKET_30DAY, user.getUser_cycle_bucket_30days());
+
+        // 1day features
+        makeFea(VlogFeatureGroup.USER_1DAY_EXP, user.getDay1_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.USER_1DAY_CLICK, user.getDay1_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.USER_1DAY_SHARE, user.getDay1_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.USER_1DAY_RETURN, user.getDay1_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.USER_1DAY_CTR, user.getDay1_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.USER_1DAY_STR, user.getDay1_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.USER_1DAY_ROV, user.getDay1_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.USER_1DAY_ROS, user.getDay1_cnt_features().get("ros"));
+
+        // 3day features
+        makeFea(VlogFeatureGroup.USER_3DAY_EXP, user.getDay3_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.USER_3DAY_CLICK, user.getDay3_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.USER_3DAY_SHARE, user.getDay3_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.USER_3DAY_RETURN, user.getDay3_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.USER_3DAY_CTR, user.getDay3_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.USER_3DAY_STR, user.getDay3_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.USER_3DAY_ROV, user.getDay3_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.USER_3DAY_ROS, user.getDay3_cnt_features().get("ros"));
+
+        // 7day features
+        makeFea(VlogFeatureGroup.USER_7DAY_EXP, user.getDay7_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.USER_7DAY_CLICK, user.getDay7_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.USER_7DAY_SHARE, user.getDay7_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.USER_7DAY_RETURN, user.getDay7_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.USER_7DAY_CTR, user.getDay7_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.USER_7DAY_STR, user.getDay7_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.USER_7DAY_ROV, user.getDay7_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.USER_7DAY_ROS, user.getDay7_cnt_features().get("ros"));
+
+        // 3month features
+        makeFea(VlogFeatureGroup.USER_3MONTH_EXP, user.getMonth3_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_CLICK, user.getMonth3_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_SHARE, user.getMonth3_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_RETURN, user.getMonth3_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_CTR, user.getMonth3_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_STR, user.getMonth3_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_ROV, user.getMonth3_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.USER_3MONTH_ROS, user.getMonth3_cnt_features().get("ros"));
+
+    }
+
+    public void getItemFeature(VideoBytesFeature item) {
+        makeFea(VlogFeatureGroup.VIDEOID, item.getVideoId());
+        makeFea(VlogFeatureGroup.UP_ID, item.getUpId());
+        // 1day features
+        makeFea(VlogFeatureGroup.ITEM_1DAY_EXP, item.getItem_day1_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_CLICK, item.getItem_day1_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_SHARE, item.getItem_day1_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_RETURN, item.getItem_day1_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_CTR, item.getItem_day1_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_STR, item.getItem_day1_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_ROV, item.getItem_day1_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.ITEM_1DAY_ROS, item.getItem_day1_cnt_features().get("ros"));
+
+        // 3day features
+        makeFea(VlogFeatureGroup.ITEM_3DAY_EXP, item.getItem_day1_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_CLICK, item.getItem_day1_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_SHARE, item.getItem_day1_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_RETURN, item.getItem_day1_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_CTR, item.getItem_day1_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_STR, item.getItem_day1_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_ROV, item.getItem_day1_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.ITEM_3DAY_ROS, item.getItem_day1_cnt_features().get("ros"));
+
+        // 7day features
+        makeFea(VlogFeatureGroup.ITEM_7DAY_EXP, item.getItem_day7_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_CLICK, item.getItem_day7_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_SHARE, item.getItem_day7_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_RETURN, item.getItem_day7_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_CTR, item.getItem_day7_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_STR, item.getItem_day7_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_ROV, item.getItem_day7_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.ITEM_7DAY_ROS, item.getItem_day7_cnt_features().get("ros"));
+
+        // 3month features
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_EXP, item.getItem_month3_cnt_features().get("exp"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_CLICK, item.getItem_month3_cnt_features().get("click"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_SHARE, item.getItem_month3_cnt_features().get("share"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_RETURN, item.getItem_month3_cnt_features().get("return"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_CTR, item.getItem_month3_cnt_features().get("ctr"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_STR, item.getItem_month3_cnt_features().get("str"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_ROV, item.getItem_month3_cnt_features().get("rov"));
+        makeFea(VlogFeatureGroup.ITEM_3MONTH_ROS, item.getItem_month3_cnt_features().get("ros"));
+
+    }
+
+    @Override
+    public synchronized LRSamples single(UserBytesFeature userBytesFeature,
+                            VideoBytesFeature videoBytesFeature,
+                            RequestContextBytesFeature requestContextBytesFeature) {
+        features.clear();
+        // extract features
+        getUserFeatures(userBytesFeature);
+        getContextFeatures(requestContextBytesFeature);
+        getItemFeature(videoBytesFeature);
+
+        LRSamples.Builder lr = LRSamples.newBuilder();
+        lr.setGroupNum(groupCount);
+        List<FeatureGroup> keys = new ArrayList<>(features.keySet());
+        int count = 0;
+        for(FeatureGroup group : keys) {
+            List<BaseFeature> fea = features.get(group);
+            GroupedFeature.Builder gf = GroupedFeature.newBuilder();
+            gf.setGroup(group);
+            gf.setCount(fea.size());
+            gf.addAllFeatures(fea);
+            count += fea.size();
+            lr.addFeatures(gf);
+        }
+        lr.setCount(count);
+        return lr.build();
+    }
+
+
+}

+ 819 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/BaseFeature.java

@@ -0,0 +1,819 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code BaseFeature}
+ */
+public final class BaseFeature extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:BaseFeature)
+    BaseFeatureOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BaseFeature.newBuilder() to construct.
+  private BaseFeature(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BaseFeature() {
+    fea_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new BaseFeature();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BaseFeature(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            id_ = input.readInt64();
+            break;
+          }
+          case 16: {
+
+            identifier_ = input.readInt64();
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            fea_ = s;
+            break;
+          }
+          case 33: {
+
+            value_ = input.readDouble();
+            break;
+          }
+          case 41: {
+
+            weight_ = input.readDouble();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return CtrSamples.internal_static_BaseFeature_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return CtrSamples.internal_static_BaseFeature_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            BaseFeature.class, BaseFeature.Builder.class);
+  }
+
+  public static final int ID_FIELD_NUMBER = 1;
+  private long id_;
+  /**
+   * <code>int64 id = 1;</code>
+   * @return The id.
+   */
+  @java.lang.Override
+  public long getId() {
+    return id_;
+  }
+
+  public static final int IDENTIFIER_FIELD_NUMBER = 2;
+  private long identifier_;
+  /**
+   * <code>int64 identifier = 2;</code>
+   * @return The identifier.
+   */
+  @java.lang.Override
+  public long getIdentifier() {
+    return identifier_;
+  }
+
+  public static final int FEA_FIELD_NUMBER = 3;
+  private volatile java.lang.Object fea_;
+  /**
+   * <code>string fea = 3;</code>
+   * @return The fea.
+   */
+  @java.lang.Override
+  public java.lang.String getFea() {
+    java.lang.Object ref = fea_;
+    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();
+      fea_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string fea = 3;</code>
+   * @return The bytes for fea.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getFeaBytes() {
+    java.lang.Object ref = fea_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      fea_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int VALUE_FIELD_NUMBER = 4;
+  private double value_;
+  /**
+   * <code>double value = 4;</code>
+   * @return The value.
+   */
+  @java.lang.Override
+  public double getValue() {
+    return value_;
+  }
+
+  public static final int WEIGHT_FIELD_NUMBER = 5;
+  private double weight_;
+  /**
+   * <code>double weight = 5;</code>
+   * @return The weight.
+   */
+  @java.lang.Override
+  public double getWeight() {
+    return weight_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (id_ != 0L) {
+      output.writeInt64(1, id_);
+    }
+    if (identifier_ != 0L) {
+      output.writeInt64(2, identifier_);
+    }
+    if (!getFeaBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, fea_);
+    }
+    if (value_ != 0D) {
+      output.writeDouble(4, value_);
+    }
+    if (weight_ != 0D) {
+      output.writeDouble(5, weight_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (id_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, id_);
+    }
+    if (identifier_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, identifier_);
+    }
+    if (!getFeaBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, fea_);
+    }
+    if (value_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(4, value_);
+    }
+    if (weight_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(5, weight_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof BaseFeature)) {
+      return super.equals(obj);
+    }
+    BaseFeature other = (BaseFeature) obj;
+
+    if (getId()
+        != other.getId()) return false;
+    if (getIdentifier()
+        != other.getIdentifier()) return false;
+    if (!getFea()
+        .equals(other.getFea())) return false;
+    if (java.lang.Double.doubleToLongBits(getValue())
+        != java.lang.Double.doubleToLongBits(
+            other.getValue())) return false;
+    if (java.lang.Double.doubleToLongBits(getWeight())
+        != java.lang.Double.doubleToLongBits(
+            other.getWeight())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getId());
+    hash = (37 * hash) + IDENTIFIER_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getIdentifier());
+    hash = (37 * hash) + FEA_FIELD_NUMBER;
+    hash = (53 * hash) + getFea().hashCode();
+    hash = (37 * hash) + VALUE_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getValue()));
+    hash = (37 * hash) + WEIGHT_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getWeight()));
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static BaseFeature parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static BaseFeature parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static BaseFeature parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static BaseFeature parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static BaseFeature parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static BaseFeature parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static BaseFeature parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static BaseFeature parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static BaseFeature parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static BaseFeature parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static BaseFeature parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static BaseFeature parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(BaseFeature prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code BaseFeature}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:BaseFeature)
+          BaseFeatureOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return CtrSamples.internal_static_BaseFeature_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return CtrSamples.internal_static_BaseFeature_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              BaseFeature.class, BaseFeature.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.BaseFeature.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      id_ = 0L;
+
+      identifier_ = 0L;
+
+      fea_ = "";
+
+      value_ = 0D;
+
+      weight_ = 0D;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return CtrSamples.internal_static_BaseFeature_descriptor;
+    }
+
+    @java.lang.Override
+    public BaseFeature getDefaultInstanceForType() {
+      return BaseFeature.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public BaseFeature build() {
+      BaseFeature result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public BaseFeature buildPartial() {
+      BaseFeature result = new BaseFeature(this);
+      result.id_ = id_;
+      result.identifier_ = identifier_;
+      result.fea_ = fea_;
+      result.value_ = value_;
+      result.weight_ = weight_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof BaseFeature) {
+        return mergeFrom((BaseFeature)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(BaseFeature other) {
+      if (other == BaseFeature.getDefaultInstance()) return this;
+      if (other.getId() != 0L) {
+        setId(other.getId());
+      }
+      if (other.getIdentifier() != 0L) {
+        setIdentifier(other.getIdentifier());
+      }
+      if (!other.getFea().isEmpty()) {
+        fea_ = other.fea_;
+        onChanged();
+      }
+      if (other.getValue() != 0D) {
+        setValue(other.getValue());
+      }
+      if (other.getWeight() != 0D) {
+        setWeight(other.getWeight());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      BaseFeature parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (BaseFeature) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long id_ ;
+    /**
+     * <code>int64 id = 1;</code>
+     * @return The id.
+     */
+    @java.lang.Override
+    public long getId() {
+      return id_;
+    }
+    /**
+     * <code>int64 id = 1;</code>
+     * @param value The id to set.
+     * @return This builder for chaining.
+     */
+    public Builder setId(long value) {
+      
+      id_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 id = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearId() {
+      
+      id_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private long identifier_ ;
+    /**
+     * <code>int64 identifier = 2;</code>
+     * @return The identifier.
+     */
+    @java.lang.Override
+    public long getIdentifier() {
+      return identifier_;
+    }
+    /**
+     * <code>int64 identifier = 2;</code>
+     * @param value The identifier to set.
+     * @return This builder for chaining.
+     */
+    public Builder setIdentifier(long value) {
+      
+      identifier_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 identifier = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearIdentifier() {
+      
+      identifier_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object fea_ = "";
+    /**
+     * <code>string fea = 3;</code>
+     * @return The fea.
+     */
+    public java.lang.String getFea() {
+      java.lang.Object ref = fea_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        fea_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string fea = 3;</code>
+     * @return The bytes for fea.
+     */
+    public com.google.protobuf.ByteString
+        getFeaBytes() {
+      java.lang.Object ref = fea_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        fea_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string fea = 3;</code>
+     * @param value The fea to set.
+     * @return This builder for chaining.
+     */
+    public Builder setFea(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      fea_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string fea = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearFea() {
+      
+      fea_ = getDefaultInstance().getFea();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string fea = 3;</code>
+     * @param value The bytes for fea to set.
+     * @return This builder for chaining.
+     */
+    public Builder setFeaBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      fea_ = value;
+      onChanged();
+      return this;
+    }
+
+    private double value_ ;
+    /**
+     * <code>double value = 4;</code>
+     * @return The value.
+     */
+    @java.lang.Override
+    public double getValue() {
+      return value_;
+    }
+    /**
+     * <code>double value = 4;</code>
+     * @param value The value to set.
+     * @return This builder for chaining.
+     */
+    public Builder setValue(double value) {
+      
+      value_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double value = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearValue() {
+      
+      value_ = 0D;
+      onChanged();
+      return this;
+    }
+
+    private double weight_ ;
+    /**
+     * <code>double weight = 5;</code>
+     * @return The weight.
+     */
+    @java.lang.Override
+    public double getWeight() {
+      return weight_;
+    }
+    /**
+     * <code>double weight = 5;</code>
+     * @param value The weight to set.
+     * @return This builder for chaining.
+     */
+    public Builder setWeight(double value) {
+      
+      weight_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double weight = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearWeight() {
+      
+      weight_ = 0D;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:BaseFeature)
+  }
+
+  // @@protoc_insertion_point(class_scope:BaseFeature)
+  private static final BaseFeature DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new BaseFeature();
+  }
+
+  public static BaseFeature getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BaseFeature>
+      PARSER = new com.google.protobuf.AbstractParser<BaseFeature>() {
+    @java.lang.Override
+    public BaseFeature parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BaseFeature(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BaseFeature> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BaseFeature> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public BaseFeature getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 45 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/BaseFeatureOrBuilder.java

@@ -0,0 +1,45 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface BaseFeatureOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:BaseFeature)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 id = 1;</code>
+   * @return The id.
+   */
+  long getId();
+
+  /**
+   * <code>int64 identifier = 2;</code>
+   * @return The identifier.
+   */
+  long getIdentifier();
+
+  /**
+   * <code>string fea = 3;</code>
+   * @return The fea.
+   */
+  java.lang.String getFea();
+  /**
+   * <code>string fea = 3;</code>
+   * @return The bytes for fea.
+   */
+  com.google.protobuf.ByteString
+      getFeaBytes();
+
+  /**
+   * <code>double value = 4;</code>
+   * @return The value.
+   */
+  double getValue();
+
+  /**
+   * <code>double weight = 5;</code>
+   * @return The weight.
+   */
+  double getWeight();
+}

+ 104 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/CtrSamples.java

@@ -0,0 +1,104 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public final class CtrSamples {
+  private CtrSamples() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_FeatureGroup_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_FeatureGroup_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_BaseFeature_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_BaseFeature_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_GroupedFeature_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_GroupedFeature_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_LRWeight_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_LRWeight_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_LRSamples_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_LRSamples_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n4com/tzld/piaoquan/recommend/server/ctr" +
+      "_samples.proto\"E\n\014FeatureGroup\022\014\n\004type\030\001" +
+      " \001(\t\022\n\n\002id\030\002 \001(\005\022\014\n\004name\030\003 \001(\t\022\r\n\005field\030" +
+      "\004 \001(\t\"Y\n\013BaseFeature\022\n\n\002id\030\001 \001(\003\022\022\n\niden" +
+      "tifier\030\002 \001(\003\022\013\n\003fea\030\003 \001(\t\022\r\n\005value\030\004 \001(\001" +
+      "\022\016\n\006weight\030\005 \001(\001\"]\n\016GroupedFeature\022\034\n\005gr" +
+      "oup\030\001 \001(\0132\r.FeatureGroup\022\r\n\005count\030\002 \001(\005\022" +
+      "\036\n\010features\030\003 \003(\0132\014.BaseFeature\"=\n\010LRWei" +
+      "ght\022\021\n\tgroup_num\030\001 \001(\005\022\036\n\010features\030\002 \003(\013" +
+      "2\014.BaseFeature\"\207\001\n\tLRSamples\022\020\n\010is_click" +
+      "\030\001 \001(\005\022\021\n\tgroup_num\030\002 \001(\005\022\r\n\005count\030\003 \001(\005" +
+      "\022!\n\010features\030\004 \003(\0132\017.GroupedFeature\022\016\n\006w" +
+      "eight\030\005 \001(\001\022\023\n\013predict_ctr\030\006 \001(\001B7\n0com." +
+      "tzld.piaoquan.recommend.server.gen.recom" +
+      "mendP\001\210\001\001b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_FeatureGroup_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_FeatureGroup_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_FeatureGroup_descriptor,
+        new java.lang.String[] { "Type", "Id", "Name", "Field", });
+    internal_static_BaseFeature_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_BaseFeature_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_BaseFeature_descriptor,
+        new java.lang.String[] { "Id", "Identifier", "Fea", "Value", "Weight", });
+    internal_static_GroupedFeature_descriptor =
+      getDescriptor().getMessageTypes().get(2);
+    internal_static_GroupedFeature_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_GroupedFeature_descriptor,
+        new java.lang.String[] { "Group", "Count", "Features", });
+    internal_static_LRWeight_descriptor =
+      getDescriptor().getMessageTypes().get(3);
+    internal_static_LRWeight_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_LRWeight_descriptor,
+        new java.lang.String[] { "GroupNum", "Features", });
+    internal_static_LRSamples_descriptor =
+      getDescriptor().getMessageTypes().get(4);
+    internal_static_LRSamples_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_LRSamples_descriptor,
+        new java.lang.String[] { "IsClick", "GroupNum", "Count", "Features", "Weight", "PredictCtr", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

+ 897 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/FeatureGroup.java

@@ -0,0 +1,897 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code FeatureGroup}
+ */
+public final class FeatureGroup extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:FeatureGroup)
+    FeatureGroupOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use FeatureGroup.newBuilder() to construct.
+  private FeatureGroup(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private FeatureGroup() {
+    type_ = "";
+    name_ = "";
+    field_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new FeatureGroup();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private FeatureGroup(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            type_ = s;
+            break;
+          }
+          case 16: {
+
+            id_ = input.readInt32();
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            name_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            field_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return CtrSamples.internal_static_FeatureGroup_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return CtrSamples.internal_static_FeatureGroup_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            FeatureGroup.class, FeatureGroup.Builder.class);
+  }
+
+  public static final int TYPE_FIELD_NUMBER = 1;
+  private volatile java.lang.Object type_;
+  /**
+   * <code>string type = 1;</code>
+   * @return The type.
+   */
+  @java.lang.Override
+  public java.lang.String getType() {
+    java.lang.Object ref = type_;
+    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();
+      type_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string type = 1;</code>
+   * @return The bytes for type.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getTypeBytes() {
+    java.lang.Object ref = type_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      type_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int ID_FIELD_NUMBER = 2;
+  private int id_;
+  /**
+   * <code>int32 id = 2;</code>
+   * @return The id.
+   */
+  @java.lang.Override
+  public int getId() {
+    return id_;
+  }
+
+  public static final int NAME_FIELD_NUMBER = 3;
+  private volatile java.lang.Object name_;
+  /**
+   * <code>string name = 3;</code>
+   * @return The name.
+   */
+  @java.lang.Override
+  public java.lang.String getName() {
+    java.lang.Object ref = name_;
+    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();
+      name_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string name = 3;</code>
+   * @return The bytes for name.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getNameBytes() {
+    java.lang.Object ref = name_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      name_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int FIELD_FIELD_NUMBER = 4;
+  private volatile java.lang.Object field_;
+  /**
+   * <code>string field = 4;</code>
+   * @return The field.
+   */
+  @java.lang.Override
+  public java.lang.String getField() {
+    java.lang.Object ref = field_;
+    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();
+      field_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string field = 4;</code>
+   * @return The bytes for field.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getFieldBytes() {
+    java.lang.Object ref = field_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      field_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getTypeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, type_);
+    }
+    if (id_ != 0) {
+      output.writeInt32(2, id_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, name_);
+    }
+    if (!getFieldBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, field_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getTypeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, type_);
+    }
+    if (id_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(2, id_);
+    }
+    if (!getNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, name_);
+    }
+    if (!getFieldBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, field_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof FeatureGroup)) {
+      return super.equals(obj);
+    }
+    FeatureGroup other = (FeatureGroup) obj;
+
+    if (!getType()
+        .equals(other.getType())) return false;
+    if (getId()
+        != other.getId()) return false;
+    if (!getName()
+        .equals(other.getName())) return false;
+    if (!getField()
+        .equals(other.getField())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + TYPE_FIELD_NUMBER;
+    hash = (53 * hash) + getType().hashCode();
+    hash = (37 * hash) + ID_FIELD_NUMBER;
+    hash = (53 * hash) + getId();
+    hash = (37 * hash) + NAME_FIELD_NUMBER;
+    hash = (53 * hash) + getName().hashCode();
+    hash = (37 * hash) + FIELD_FIELD_NUMBER;
+    hash = (53 * hash) + getField().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static FeatureGroup parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static FeatureGroup parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static FeatureGroup parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static FeatureGroup parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static FeatureGroup parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static FeatureGroup parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static FeatureGroup parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static FeatureGroup parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static FeatureGroup parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static FeatureGroup parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static FeatureGroup parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static FeatureGroup parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(FeatureGroup prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code FeatureGroup}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:FeatureGroup)
+          FeatureGroupOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return CtrSamples.internal_static_FeatureGroup_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return CtrSamples.internal_static_FeatureGroup_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              FeatureGroup.class, FeatureGroup.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.FeatureGroup.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      type_ = "";
+
+      id_ = 0;
+
+      name_ = "";
+
+      field_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return CtrSamples.internal_static_FeatureGroup_descriptor;
+    }
+
+    @java.lang.Override
+    public FeatureGroup getDefaultInstanceForType() {
+      return FeatureGroup.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public FeatureGroup build() {
+      FeatureGroup result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public FeatureGroup buildPartial() {
+      FeatureGroup result = new FeatureGroup(this);
+      result.type_ = type_;
+      result.id_ = id_;
+      result.name_ = name_;
+      result.field_ = field_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof FeatureGroup) {
+        return mergeFrom((FeatureGroup)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(FeatureGroup other) {
+      if (other == FeatureGroup.getDefaultInstance()) return this;
+      if (!other.getType().isEmpty()) {
+        type_ = other.type_;
+        onChanged();
+      }
+      if (other.getId() != 0) {
+        setId(other.getId());
+      }
+      if (!other.getName().isEmpty()) {
+        name_ = other.name_;
+        onChanged();
+      }
+      if (!other.getField().isEmpty()) {
+        field_ = other.field_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      FeatureGroup parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (FeatureGroup) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object type_ = "";
+    /**
+     * <code>string type = 1;</code>
+     * @return The type.
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        type_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string type = 1;</code>
+     * @return The bytes for type.
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string type = 1;</code>
+     * @param value The type to set.
+     * @return This builder for chaining.
+     */
+    public Builder setType(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      type_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string type = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearType() {
+      
+      type_ = getDefaultInstance().getType();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string type = 1;</code>
+     * @param value The bytes for type to set.
+     * @return This builder for chaining.
+     */
+    public Builder setTypeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      type_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int id_ ;
+    /**
+     * <code>int32 id = 2;</code>
+     * @return The id.
+     */
+    @java.lang.Override
+    public int getId() {
+      return id_;
+    }
+    /**
+     * <code>int32 id = 2;</code>
+     * @param value The id to set.
+     * @return This builder for chaining.
+     */
+    public Builder setId(int value) {
+      
+      id_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 id = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearId() {
+      
+      id_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object name_ = "";
+    /**
+     * <code>string name = 3;</code>
+     * @return The name.
+     */
+    public java.lang.String getName() {
+      java.lang.Object ref = name_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        name_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @return The bytes for name.
+     */
+    public com.google.protobuf.ByteString
+        getNameBytes() {
+      java.lang.Object ref = name_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        name_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @param value The name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      name_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearName() {
+      
+      name_ = getDefaultInstance().getName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string name = 3;</code>
+     * @param value The bytes for name to set.
+     * @return This builder for chaining.
+     */
+    public Builder setNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      name_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object field_ = "";
+    /**
+     * <code>string field = 4;</code>
+     * @return The field.
+     */
+    public java.lang.String getField() {
+      java.lang.Object ref = field_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        field_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string field = 4;</code>
+     * @return The bytes for field.
+     */
+    public com.google.protobuf.ByteString
+        getFieldBytes() {
+      java.lang.Object ref = field_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        field_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string field = 4;</code>
+     * @param value The field to set.
+     * @return This builder for chaining.
+     */
+    public Builder setField(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      field_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string field = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearField() {
+      
+      field_ = getDefaultInstance().getField();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string field = 4;</code>
+     * @param value The bytes for field to set.
+     * @return This builder for chaining.
+     */
+    public Builder setFieldBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      field_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:FeatureGroup)
+  }
+
+  // @@protoc_insertion_point(class_scope:FeatureGroup)
+  private static final FeatureGroup DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new FeatureGroup();
+  }
+
+  public static FeatureGroup getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<FeatureGroup>
+      PARSER = new com.google.protobuf.AbstractParser<FeatureGroup>() {
+    @java.lang.Override
+    public FeatureGroup parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new FeatureGroup(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<FeatureGroup> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<FeatureGroup> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public FeatureGroup getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 51 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/FeatureGroupOrBuilder.java

@@ -0,0 +1,51 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface FeatureGroupOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:FeatureGroup)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string type = 1;</code>
+   * @return The type.
+   */
+  java.lang.String getType();
+  /**
+   * <code>string type = 1;</code>
+   * @return The bytes for type.
+   */
+  com.google.protobuf.ByteString
+      getTypeBytes();
+
+  /**
+   * <code>int32 id = 2;</code>
+   * @return The id.
+   */
+  int getId();
+
+  /**
+   * <code>string name = 3;</code>
+   * @return The name.
+   */
+  java.lang.String getName();
+  /**
+   * <code>string name = 3;</code>
+   * @return The bytes for name.
+   */
+  com.google.protobuf.ByteString
+      getNameBytes();
+
+  /**
+   * <code>string field = 4;</code>
+   * @return The field.
+   */
+  java.lang.String getField();
+  /**
+   * <code>string field = 4;</code>
+   * @return The bytes for field.
+   */
+  com.google.protobuf.ByteString
+      getFieldBytes();
+}

+ 1022 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/GroupedFeature.java

@@ -0,0 +1,1022 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code GroupedFeature}
+ */
+public final class GroupedFeature extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:GroupedFeature)
+    GroupedFeatureOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GroupedFeature.newBuilder() to construct.
+  private GroupedFeature(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GroupedFeature() {
+    features_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new GroupedFeature();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GroupedFeature(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            FeatureGroup.Builder subBuilder = null;
+            if (group_ != null) {
+              subBuilder = group_.toBuilder();
+            }
+            group_ = input.readMessage(FeatureGroup.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(group_);
+              group_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+
+            count_ = input.readInt32();
+            break;
+          }
+          case 26: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              features_ = new java.util.ArrayList<BaseFeature>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            features_.add(
+                input.readMessage(BaseFeature.parser(), extensionRegistry));
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        features_ = java.util.Collections.unmodifiableList(features_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return CtrSamples.internal_static_GroupedFeature_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return CtrSamples.internal_static_GroupedFeature_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            GroupedFeature.class, GroupedFeature.Builder.class);
+  }
+
+  public static final int GROUP_FIELD_NUMBER = 1;
+  private FeatureGroup group_;
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   * @return Whether the group field is set.
+   */
+  @java.lang.Override
+  public boolean hasGroup() {
+    return group_ != null;
+  }
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   * @return The group.
+   */
+  @java.lang.Override
+  public FeatureGroup getGroup() {
+    return group_ == null ? FeatureGroup.getDefaultInstance() : group_;
+  }
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   */
+  @java.lang.Override
+  public FeatureGroupOrBuilder getGroupOrBuilder() {
+    return getGroup();
+  }
+
+  public static final int COUNT_FIELD_NUMBER = 2;
+  private int count_;
+  /**
+   * <code>int32 count = 2;</code>
+   * @return The count.
+   */
+  @java.lang.Override
+  public int getCount() {
+    return count_;
+  }
+
+  public static final int FEATURES_FIELD_NUMBER = 3;
+  private java.util.List<BaseFeature> features_;
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  @java.lang.Override
+  public java.util.List<BaseFeature> getFeaturesList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  @java.lang.Override
+  public java.util.List<? extends BaseFeatureOrBuilder>
+      getFeaturesOrBuilderList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  @java.lang.Override
+  public int getFeaturesCount() {
+    return features_.size();
+  }
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  @java.lang.Override
+  public BaseFeature getFeatures(int index) {
+    return features_.get(index);
+  }
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  @java.lang.Override
+  public BaseFeatureOrBuilder getFeaturesOrBuilder(
+      int index) {
+    return features_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (group_ != null) {
+      output.writeMessage(1, getGroup());
+    }
+    if (count_ != 0) {
+      output.writeInt32(2, count_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      output.writeMessage(3, features_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (group_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getGroup());
+    }
+    if (count_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(2, count_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(3, features_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof GroupedFeature)) {
+      return super.equals(obj);
+    }
+    GroupedFeature other = (GroupedFeature) obj;
+
+    if (hasGroup() != other.hasGroup()) return false;
+    if (hasGroup()) {
+      if (!getGroup()
+          .equals(other.getGroup())) return false;
+    }
+    if (getCount()
+        != other.getCount()) return false;
+    if (!getFeaturesList()
+        .equals(other.getFeaturesList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasGroup()) {
+      hash = (37 * hash) + GROUP_FIELD_NUMBER;
+      hash = (53 * hash) + getGroup().hashCode();
+    }
+    hash = (37 * hash) + COUNT_FIELD_NUMBER;
+    hash = (53 * hash) + getCount();
+    if (getFeaturesCount() > 0) {
+      hash = (37 * hash) + FEATURES_FIELD_NUMBER;
+      hash = (53 * hash) + getFeaturesList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static GroupedFeature parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static GroupedFeature parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static GroupedFeature parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static GroupedFeature parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static GroupedFeature parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static GroupedFeature parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static GroupedFeature parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static GroupedFeature parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static GroupedFeature parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static GroupedFeature parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static GroupedFeature parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static GroupedFeature parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(GroupedFeature prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code GroupedFeature}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:GroupedFeature)
+          GroupedFeatureOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return CtrSamples.internal_static_GroupedFeature_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return CtrSamples.internal_static_GroupedFeature_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              GroupedFeature.class, GroupedFeature.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.GroupedFeature.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getFeaturesFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (groupBuilder_ == null) {
+        group_ = null;
+      } else {
+        group_ = null;
+        groupBuilder_ = null;
+      }
+      count_ = 0;
+
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        featuresBuilder_.clear();
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return CtrSamples.internal_static_GroupedFeature_descriptor;
+    }
+
+    @java.lang.Override
+    public GroupedFeature getDefaultInstanceForType() {
+      return GroupedFeature.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public GroupedFeature build() {
+      GroupedFeature result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public GroupedFeature buildPartial() {
+      GroupedFeature result = new GroupedFeature(this);
+      int from_bitField0_ = bitField0_;
+      if (groupBuilder_ == null) {
+        result.group_ = group_;
+      } else {
+        result.group_ = groupBuilder_.build();
+      }
+      result.count_ = count_;
+      if (featuresBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) != 0)) {
+          features_ = java.util.Collections.unmodifiableList(features_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.features_ = features_;
+      } else {
+        result.features_ = featuresBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof GroupedFeature) {
+        return mergeFrom((GroupedFeature)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(GroupedFeature other) {
+      if (other == GroupedFeature.getDefaultInstance()) return this;
+      if (other.hasGroup()) {
+        mergeGroup(other.getGroup());
+      }
+      if (other.getCount() != 0) {
+        setCount(other.getCount());
+      }
+      if (featuresBuilder_ == null) {
+        if (!other.features_.isEmpty()) {
+          if (features_.isEmpty()) {
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureFeaturesIsMutable();
+            features_.addAll(other.features_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.features_.isEmpty()) {
+          if (featuresBuilder_.isEmpty()) {
+            featuresBuilder_.dispose();
+            featuresBuilder_ = null;
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            featuresBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getFeaturesFieldBuilder() : null;
+          } else {
+            featuresBuilder_.addAllMessages(other.features_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      GroupedFeature parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (GroupedFeature) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private FeatureGroup group_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+            FeatureGroup, FeatureGroup.Builder, FeatureGroupOrBuilder> groupBuilder_;
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     * @return Whether the group field is set.
+     */
+    public boolean hasGroup() {
+      return groupBuilder_ != null || group_ != null;
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     * @return The group.
+     */
+    public FeatureGroup getGroup() {
+      if (groupBuilder_ == null) {
+        return group_ == null ? FeatureGroup.getDefaultInstance() : group_;
+      } else {
+        return groupBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public Builder setGroup(FeatureGroup value) {
+      if (groupBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        group_ = value;
+        onChanged();
+      } else {
+        groupBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public Builder setGroup(
+        FeatureGroup.Builder builderForValue) {
+      if (groupBuilder_ == null) {
+        group_ = builderForValue.build();
+        onChanged();
+      } else {
+        groupBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public Builder mergeGroup(FeatureGroup value) {
+      if (groupBuilder_ == null) {
+        if (group_ != null) {
+          group_ =
+            FeatureGroup.newBuilder(group_).mergeFrom(value).buildPartial();
+        } else {
+          group_ = value;
+        }
+        onChanged();
+      } else {
+        groupBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public Builder clearGroup() {
+      if (groupBuilder_ == null) {
+        group_ = null;
+        onChanged();
+      } else {
+        group_ = null;
+        groupBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public FeatureGroup.Builder getGroupBuilder() {
+      
+      onChanged();
+      return getGroupFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    public FeatureGroupOrBuilder getGroupOrBuilder() {
+      if (groupBuilder_ != null) {
+        return groupBuilder_.getMessageOrBuilder();
+      } else {
+        return group_ == null ?
+            FeatureGroup.getDefaultInstance() : group_;
+      }
+    }
+    /**
+     * <code>.FeatureGroup group = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+            FeatureGroup, FeatureGroup.Builder, FeatureGroupOrBuilder>
+        getGroupFieldBuilder() {
+      if (groupBuilder_ == null) {
+        groupBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+                FeatureGroup, FeatureGroup.Builder, FeatureGroupOrBuilder>(
+                getGroup(),
+                getParentForChildren(),
+                isClean());
+        group_ = null;
+      }
+      return groupBuilder_;
+    }
+
+    private int count_ ;
+    /**
+     * <code>int32 count = 2;</code>
+     * @return The count.
+     */
+    @java.lang.Override
+    public int getCount() {
+      return count_;
+    }
+    /**
+     * <code>int32 count = 2;</code>
+     * @param value The count to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCount(int value) {
+      
+      count_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 count = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCount() {
+      
+      count_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.util.List<BaseFeature> features_ =
+      java.util.Collections.emptyList();
+    private void ensureFeaturesIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        features_ = new java.util.ArrayList<BaseFeature>(features_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder> featuresBuilder_;
+
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public java.util.List<BaseFeature> getFeaturesList() {
+      if (featuresBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(features_);
+      } else {
+        return featuresBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public int getFeaturesCount() {
+      if (featuresBuilder_ == null) {
+        return features_.size();
+      } else {
+        return featuresBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public BaseFeature getFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);
+      } else {
+        return featuresBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder setFeatures(
+        int index, BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.set(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder setFeatures(
+        int index, BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder addFeatures(BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder addFeatures(
+        int index, BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder addFeatures(
+        BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder addFeatures(
+        int index, BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder addAllFeatures(
+        java.lang.Iterable<? extends BaseFeature> values) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, features_);
+        onChanged();
+      } else {
+        featuresBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder clearFeatures() {
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        featuresBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public Builder removeFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.remove(index);
+        onChanged();
+      } else {
+        featuresBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public BaseFeature.Builder getFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public BaseFeatureOrBuilder getFeaturesOrBuilder(
+        int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);  } else {
+        return featuresBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public java.util.List<? extends BaseFeatureOrBuilder>
+         getFeaturesOrBuilderList() {
+      if (featuresBuilder_ != null) {
+        return featuresBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(features_);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public BaseFeature.Builder addFeaturesBuilder() {
+      return getFeaturesFieldBuilder().addBuilder(
+          BaseFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public BaseFeature.Builder addFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().addBuilder(
+          index, BaseFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .BaseFeature features = 3;</code>
+     */
+    public java.util.List<BaseFeature.Builder>
+         getFeaturesBuilderList() {
+      return getFeaturesFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder>
+        getFeaturesFieldBuilder() {
+      if (featuresBuilder_ == null) {
+        featuresBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+                BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder>(
+                features_,
+                ((bitField0_ & 0x00000001) != 0),
+                getParentForChildren(),
+                isClean());
+        features_ = null;
+      }
+      return featuresBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:GroupedFeature)
+  }
+
+  // @@protoc_insertion_point(class_scope:GroupedFeature)
+  private static final GroupedFeature DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new GroupedFeature();
+  }
+
+  public static GroupedFeature getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GroupedFeature>
+      PARSER = new com.google.protobuf.AbstractParser<GroupedFeature>() {
+    @java.lang.Override
+    public GroupedFeature parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GroupedFeature(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GroupedFeature> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GroupedFeature> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public GroupedFeature getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 54 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/GroupedFeatureOrBuilder.java

@@ -0,0 +1,54 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface GroupedFeatureOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:GroupedFeature)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   * @return Whether the group field is set.
+   */
+  boolean hasGroup();
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   * @return The group.
+   */
+  FeatureGroup getGroup();
+  /**
+   * <code>.FeatureGroup group = 1;</code>
+   */
+  FeatureGroupOrBuilder getGroupOrBuilder();
+
+  /**
+   * <code>int32 count = 2;</code>
+   * @return The count.
+   */
+  int getCount();
+
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  java.util.List<BaseFeature>
+      getFeaturesList();
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  BaseFeature getFeatures(int index);
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  int getFeaturesCount();
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  java.util.List<? extends BaseFeatureOrBuilder>
+      getFeaturesOrBuilderList();
+  /**
+   * <code>repeated .BaseFeature features = 3;</code>
+   */
+  BaseFeatureOrBuilder getFeaturesOrBuilder(
+      int index);
+}

+ 1094 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRSamples.java

@@ -0,0 +1,1094 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code LRSamples}
+ */
+public final class LRSamples extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:LRSamples)
+    LRSamplesOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use LRSamples.newBuilder() to construct.
+  private LRSamples(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private LRSamples() {
+    features_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new LRSamples();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private LRSamples(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            isClick_ = input.readInt32();
+            break;
+          }
+          case 16: {
+
+            groupNum_ = input.readInt32();
+            break;
+          }
+          case 24: {
+
+            count_ = input.readInt32();
+            break;
+          }
+          case 34: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              features_ = new java.util.ArrayList<GroupedFeature>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            features_.add(
+                input.readMessage(GroupedFeature.parser(), extensionRegistry));
+            break;
+          }
+          case 41: {
+
+            weight_ = input.readDouble();
+            break;
+          }
+          case 49: {
+
+            predictCtr_ = input.readDouble();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        features_ = java.util.Collections.unmodifiableList(features_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return CtrSamples.internal_static_LRSamples_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return CtrSamples.internal_static_LRSamples_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            LRSamples.class, LRSamples.Builder.class);
+  }
+
+  public static final int IS_CLICK_FIELD_NUMBER = 1;
+  private int isClick_;
+  /**
+   * <code>int32 is_click = 1;</code>
+   * @return The isClick.
+   */
+  @java.lang.Override
+  public int getIsClick() {
+    return isClick_;
+  }
+
+  public static final int GROUP_NUM_FIELD_NUMBER = 2;
+  private int groupNum_;
+  /**
+   * <code>int32 group_num = 2;</code>
+   * @return The groupNum.
+   */
+  @java.lang.Override
+  public int getGroupNum() {
+    return groupNum_;
+  }
+
+  public static final int COUNT_FIELD_NUMBER = 3;
+  private int count_;
+  /**
+   * <code>int32 count = 3;</code>
+   * @return The count.
+   */
+  @java.lang.Override
+  public int getCount() {
+    return count_;
+  }
+
+  public static final int FEATURES_FIELD_NUMBER = 4;
+  private java.util.List<GroupedFeature> features_;
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  @java.lang.Override
+  public java.util.List<GroupedFeature> getFeaturesList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  @java.lang.Override
+  public java.util.List<? extends GroupedFeatureOrBuilder>
+      getFeaturesOrBuilderList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  @java.lang.Override
+  public int getFeaturesCount() {
+    return features_.size();
+  }
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  @java.lang.Override
+  public GroupedFeature getFeatures(int index) {
+    return features_.get(index);
+  }
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  @java.lang.Override
+  public GroupedFeatureOrBuilder getFeaturesOrBuilder(
+      int index) {
+    return features_.get(index);
+  }
+
+  public static final int WEIGHT_FIELD_NUMBER = 5;
+  private double weight_;
+  /**
+   * <code>double weight = 5;</code>
+   * @return The weight.
+   */
+  @java.lang.Override
+  public double getWeight() {
+    return weight_;
+  }
+
+  public static final int PREDICT_CTR_FIELD_NUMBER = 6;
+  private double predictCtr_;
+  /**
+   * <code>double predict_ctr = 6;</code>
+   * @return The predictCtr.
+   */
+  @java.lang.Override
+  public double getPredictCtr() {
+    return predictCtr_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (isClick_ != 0) {
+      output.writeInt32(1, isClick_);
+    }
+    if (groupNum_ != 0) {
+      output.writeInt32(2, groupNum_);
+    }
+    if (count_ != 0) {
+      output.writeInt32(3, count_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      output.writeMessage(4, features_.get(i));
+    }
+    if (weight_ != 0D) {
+      output.writeDouble(5, weight_);
+    }
+    if (predictCtr_ != 0D) {
+      output.writeDouble(6, predictCtr_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (isClick_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(1, isClick_);
+    }
+    if (groupNum_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(2, groupNum_);
+    }
+    if (count_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(3, count_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(4, features_.get(i));
+    }
+    if (weight_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(5, weight_);
+    }
+    if (predictCtr_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(6, predictCtr_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof LRSamples)) {
+      return super.equals(obj);
+    }
+    LRSamples other = (LRSamples) obj;
+
+    if (getIsClick()
+        != other.getIsClick()) return false;
+    if (getGroupNum()
+        != other.getGroupNum()) return false;
+    if (getCount()
+        != other.getCount()) return false;
+    if (!getFeaturesList()
+        .equals(other.getFeaturesList())) return false;
+    if (java.lang.Double.doubleToLongBits(getWeight())
+        != java.lang.Double.doubleToLongBits(
+            other.getWeight())) return false;
+    if (java.lang.Double.doubleToLongBits(getPredictCtr())
+        != java.lang.Double.doubleToLongBits(
+            other.getPredictCtr())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + IS_CLICK_FIELD_NUMBER;
+    hash = (53 * hash) + getIsClick();
+    hash = (37 * hash) + GROUP_NUM_FIELD_NUMBER;
+    hash = (53 * hash) + getGroupNum();
+    hash = (37 * hash) + COUNT_FIELD_NUMBER;
+    hash = (53 * hash) + getCount();
+    if (getFeaturesCount() > 0) {
+      hash = (37 * hash) + FEATURES_FIELD_NUMBER;
+      hash = (53 * hash) + getFeaturesList().hashCode();
+    }
+    hash = (37 * hash) + WEIGHT_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getWeight()));
+    hash = (37 * hash) + PREDICT_CTR_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getPredictCtr()));
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static LRSamples parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRSamples parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRSamples parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRSamples parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRSamples parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRSamples parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRSamples parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static LRSamples parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static LRSamples parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static LRSamples parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static LRSamples parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static LRSamples parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(LRSamples prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code LRSamples}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:LRSamples)
+          LRSamplesOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return CtrSamples.internal_static_LRSamples_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return CtrSamples.internal_static_LRSamples_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              LRSamples.class, LRSamples.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.LRSamples.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getFeaturesFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      isClick_ = 0;
+
+      groupNum_ = 0;
+
+      count_ = 0;
+
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        featuresBuilder_.clear();
+      }
+      weight_ = 0D;
+
+      predictCtr_ = 0D;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return CtrSamples.internal_static_LRSamples_descriptor;
+    }
+
+    @java.lang.Override
+    public LRSamples getDefaultInstanceForType() {
+      return LRSamples.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public LRSamples build() {
+      LRSamples result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public LRSamples buildPartial() {
+      LRSamples result = new LRSamples(this);
+      int from_bitField0_ = bitField0_;
+      result.isClick_ = isClick_;
+      result.groupNum_ = groupNum_;
+      result.count_ = count_;
+      if (featuresBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) != 0)) {
+          features_ = java.util.Collections.unmodifiableList(features_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.features_ = features_;
+      } else {
+        result.features_ = featuresBuilder_.build();
+      }
+      result.weight_ = weight_;
+      result.predictCtr_ = predictCtr_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof LRSamples) {
+        return mergeFrom((LRSamples)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(LRSamples other) {
+      if (other == LRSamples.getDefaultInstance()) return this;
+      if (other.getIsClick() != 0) {
+        setIsClick(other.getIsClick());
+      }
+      if (other.getGroupNum() != 0) {
+        setGroupNum(other.getGroupNum());
+      }
+      if (other.getCount() != 0) {
+        setCount(other.getCount());
+      }
+      if (featuresBuilder_ == null) {
+        if (!other.features_.isEmpty()) {
+          if (features_.isEmpty()) {
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureFeaturesIsMutable();
+            features_.addAll(other.features_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.features_.isEmpty()) {
+          if (featuresBuilder_.isEmpty()) {
+            featuresBuilder_.dispose();
+            featuresBuilder_ = null;
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            featuresBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getFeaturesFieldBuilder() : null;
+          } else {
+            featuresBuilder_.addAllMessages(other.features_);
+          }
+        }
+      }
+      if (other.getWeight() != 0D) {
+        setWeight(other.getWeight());
+      }
+      if (other.getPredictCtr() != 0D) {
+        setPredictCtr(other.getPredictCtr());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      LRSamples parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (LRSamples) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private int isClick_ ;
+    /**
+     * <code>int32 is_click = 1;</code>
+     * @return The isClick.
+     */
+    @java.lang.Override
+    public int getIsClick() {
+      return isClick_;
+    }
+    /**
+     * <code>int32 is_click = 1;</code>
+     * @param value The isClick to set.
+     * @return This builder for chaining.
+     */
+    public Builder setIsClick(int value) {
+      
+      isClick_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 is_click = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearIsClick() {
+      
+      isClick_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int groupNum_ ;
+    /**
+     * <code>int32 group_num = 2;</code>
+     * @return The groupNum.
+     */
+    @java.lang.Override
+    public int getGroupNum() {
+      return groupNum_;
+    }
+    /**
+     * <code>int32 group_num = 2;</code>
+     * @param value The groupNum to set.
+     * @return This builder for chaining.
+     */
+    public Builder setGroupNum(int value) {
+      
+      groupNum_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 group_num = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearGroupNum() {
+      
+      groupNum_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int count_ ;
+    /**
+     * <code>int32 count = 3;</code>
+     * @return The count.
+     */
+    @java.lang.Override
+    public int getCount() {
+      return count_;
+    }
+    /**
+     * <code>int32 count = 3;</code>
+     * @param value The count to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCount(int value) {
+      
+      count_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 count = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCount() {
+      
+      count_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.util.List<GroupedFeature> features_ =
+      java.util.Collections.emptyList();
+    private void ensureFeaturesIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        features_ = new java.util.ArrayList<GroupedFeature>(features_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            GroupedFeature, GroupedFeature.Builder, GroupedFeatureOrBuilder> featuresBuilder_;
+
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public java.util.List<GroupedFeature> getFeaturesList() {
+      if (featuresBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(features_);
+      } else {
+        return featuresBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public int getFeaturesCount() {
+      if (featuresBuilder_ == null) {
+        return features_.size();
+      } else {
+        return featuresBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public GroupedFeature getFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);
+      } else {
+        return featuresBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder setFeatures(
+        int index, GroupedFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.set(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder setFeatures(
+        int index, GroupedFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder addFeatures(GroupedFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder addFeatures(
+        int index, GroupedFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder addFeatures(
+        GroupedFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder addFeatures(
+        int index, GroupedFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder addAllFeatures(
+        java.lang.Iterable<? extends GroupedFeature> values) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, features_);
+        onChanged();
+      } else {
+        featuresBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder clearFeatures() {
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        featuresBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public Builder removeFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.remove(index);
+        onChanged();
+      } else {
+        featuresBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public GroupedFeature.Builder getFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public GroupedFeatureOrBuilder getFeaturesOrBuilder(
+        int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);  } else {
+        return featuresBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public java.util.List<? extends GroupedFeatureOrBuilder>
+         getFeaturesOrBuilderList() {
+      if (featuresBuilder_ != null) {
+        return featuresBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(features_);
+      }
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public GroupedFeature.Builder addFeaturesBuilder() {
+      return getFeaturesFieldBuilder().addBuilder(
+          GroupedFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public GroupedFeature.Builder addFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().addBuilder(
+          index, GroupedFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .GroupedFeature features = 4;</code>
+     */
+    public java.util.List<GroupedFeature.Builder>
+         getFeaturesBuilderList() {
+      return getFeaturesFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            GroupedFeature, GroupedFeature.Builder, GroupedFeatureOrBuilder>
+        getFeaturesFieldBuilder() {
+      if (featuresBuilder_ == null) {
+        featuresBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+                GroupedFeature, GroupedFeature.Builder, GroupedFeatureOrBuilder>(
+                features_,
+                ((bitField0_ & 0x00000001) != 0),
+                getParentForChildren(),
+                isClean());
+        features_ = null;
+      }
+      return featuresBuilder_;
+    }
+
+    private double weight_ ;
+    /**
+     * <code>double weight = 5;</code>
+     * @return The weight.
+     */
+    @java.lang.Override
+    public double getWeight() {
+      return weight_;
+    }
+    /**
+     * <code>double weight = 5;</code>
+     * @param value The weight to set.
+     * @return This builder for chaining.
+     */
+    public Builder setWeight(double value) {
+      
+      weight_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double weight = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearWeight() {
+      
+      weight_ = 0D;
+      onChanged();
+      return this;
+    }
+
+    private double predictCtr_ ;
+    /**
+     * <code>double predict_ctr = 6;</code>
+     * @return The predictCtr.
+     */
+    @java.lang.Override
+    public double getPredictCtr() {
+      return predictCtr_;
+    }
+    /**
+     * <code>double predict_ctr = 6;</code>
+     * @param value The predictCtr to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPredictCtr(double value) {
+      
+      predictCtr_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double predict_ctr = 6;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearPredictCtr() {
+      
+      predictCtr_ = 0D;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:LRSamples)
+  }
+
+  // @@protoc_insertion_point(class_scope:LRSamples)
+  private static final LRSamples DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new LRSamples();
+  }
+
+  public static LRSamples getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<LRSamples>
+      PARSER = new com.google.protobuf.AbstractParser<LRSamples>() {
+    @java.lang.Override
+    public LRSamples parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new LRSamples(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<LRSamples> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<LRSamples> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public LRSamples getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 63 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRSamplesOrBuilder.java

@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface LRSamplesOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:LRSamples)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int32 is_click = 1;</code>
+   * @return The isClick.
+   */
+  int getIsClick();
+
+  /**
+   * <code>int32 group_num = 2;</code>
+   * @return The groupNum.
+   */
+  int getGroupNum();
+
+  /**
+   * <code>int32 count = 3;</code>
+   * @return The count.
+   */
+  int getCount();
+
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  java.util.List<GroupedFeature>
+      getFeaturesList();
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  GroupedFeature getFeatures(int index);
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  int getFeaturesCount();
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  java.util.List<? extends GroupedFeatureOrBuilder>
+      getFeaturesOrBuilderList();
+  /**
+   * <code>repeated .GroupedFeature features = 4;</code>
+   */
+  GroupedFeatureOrBuilder getFeaturesOrBuilder(
+      int index);
+
+  /**
+   * <code>double weight = 5;</code>
+   * @return The weight.
+   */
+  double getWeight();
+
+  /**
+   * <code>double predict_ctr = 6;</code>
+   * @return The predictCtr.
+   */
+  double getPredictCtr();
+}

+ 834 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRWeight.java

@@ -0,0 +1,834 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code LRWeight}
+ */
+public final class LRWeight extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:LRWeight)
+    LRWeightOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use LRWeight.newBuilder() to construct.
+  private LRWeight(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private LRWeight() {
+    features_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new LRWeight();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private LRWeight(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            groupNum_ = input.readInt32();
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              features_ = new java.util.ArrayList<BaseFeature>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            features_.add(
+                input.readMessage(BaseFeature.parser(), extensionRegistry));
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        features_ = java.util.Collections.unmodifiableList(features_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return CtrSamples.internal_static_LRWeight_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return CtrSamples.internal_static_LRWeight_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            LRWeight.class, LRWeight.Builder.class);
+  }
+
+  public static final int GROUP_NUM_FIELD_NUMBER = 1;
+  private int groupNum_;
+  /**
+   * <code>int32 group_num = 1;</code>
+   * @return The groupNum.
+   */
+  @java.lang.Override
+  public int getGroupNum() {
+    return groupNum_;
+  }
+
+  public static final int FEATURES_FIELD_NUMBER = 2;
+  private java.util.List<BaseFeature> features_;
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<BaseFeature> getFeaturesList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<? extends BaseFeatureOrBuilder>
+      getFeaturesOrBuilderList() {
+    return features_;
+  }
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  @java.lang.Override
+  public int getFeaturesCount() {
+    return features_.size();
+  }
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  @java.lang.Override
+  public BaseFeature getFeatures(int index) {
+    return features_.get(index);
+  }
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  @java.lang.Override
+  public BaseFeatureOrBuilder getFeaturesOrBuilder(
+      int index) {
+    return features_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (groupNum_ != 0) {
+      output.writeInt32(1, groupNum_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      output.writeMessage(2, features_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (groupNum_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(1, groupNum_);
+    }
+    for (int i = 0; i < features_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, features_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof LRWeight)) {
+      return super.equals(obj);
+    }
+    LRWeight other = (LRWeight) obj;
+
+    if (getGroupNum()
+        != other.getGroupNum()) return false;
+    if (!getFeaturesList()
+        .equals(other.getFeaturesList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + GROUP_NUM_FIELD_NUMBER;
+    hash = (53 * hash) + getGroupNum();
+    if (getFeaturesCount() > 0) {
+      hash = (37 * hash) + FEATURES_FIELD_NUMBER;
+      hash = (53 * hash) + getFeaturesList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static LRWeight parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRWeight parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRWeight parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRWeight parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRWeight parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static LRWeight parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static LRWeight parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static LRWeight parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static LRWeight parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static LRWeight parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static LRWeight parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static LRWeight parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(LRWeight prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code LRWeight}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:LRWeight)
+          LRWeightOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return CtrSamples.internal_static_LRWeight_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return CtrSamples.internal_static_LRWeight_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              LRWeight.class, LRWeight.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.LRWeight.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getFeaturesFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      groupNum_ = 0;
+
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        featuresBuilder_.clear();
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return CtrSamples.internal_static_LRWeight_descriptor;
+    }
+
+    @java.lang.Override
+    public LRWeight getDefaultInstanceForType() {
+      return LRWeight.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public LRWeight build() {
+      LRWeight result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public LRWeight buildPartial() {
+      LRWeight result = new LRWeight(this);
+      int from_bitField0_ = bitField0_;
+      result.groupNum_ = groupNum_;
+      if (featuresBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) != 0)) {
+          features_ = java.util.Collections.unmodifiableList(features_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.features_ = features_;
+      } else {
+        result.features_ = featuresBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof LRWeight) {
+        return mergeFrom((LRWeight)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(LRWeight other) {
+      if (other == LRWeight.getDefaultInstance()) return this;
+      if (other.getGroupNum() != 0) {
+        setGroupNum(other.getGroupNum());
+      }
+      if (featuresBuilder_ == null) {
+        if (!other.features_.isEmpty()) {
+          if (features_.isEmpty()) {
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureFeaturesIsMutable();
+            features_.addAll(other.features_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.features_.isEmpty()) {
+          if (featuresBuilder_.isEmpty()) {
+            featuresBuilder_.dispose();
+            featuresBuilder_ = null;
+            features_ = other.features_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            featuresBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getFeaturesFieldBuilder() : null;
+          } else {
+            featuresBuilder_.addAllMessages(other.features_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      LRWeight parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (LRWeight) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private int groupNum_ ;
+    /**
+     * <code>int32 group_num = 1;</code>
+     * @return The groupNum.
+     */
+    @java.lang.Override
+    public int getGroupNum() {
+      return groupNum_;
+    }
+    /**
+     * <code>int32 group_num = 1;</code>
+     * @param value The groupNum to set.
+     * @return This builder for chaining.
+     */
+    public Builder setGroupNum(int value) {
+      
+      groupNum_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 group_num = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearGroupNum() {
+      
+      groupNum_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.util.List<BaseFeature> features_ =
+      java.util.Collections.emptyList();
+    private void ensureFeaturesIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        features_ = new java.util.ArrayList<BaseFeature>(features_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder> featuresBuilder_;
+
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public java.util.List<BaseFeature> getFeaturesList() {
+      if (featuresBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(features_);
+      } else {
+        return featuresBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public int getFeaturesCount() {
+      if (featuresBuilder_ == null) {
+        return features_.size();
+      } else {
+        return featuresBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public BaseFeature getFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);
+      } else {
+        return featuresBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder setFeatures(
+        int index, BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.set(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder setFeatures(
+        int index, BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder addFeatures(BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder addFeatures(
+        int index, BaseFeature value) {
+      if (featuresBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureFeaturesIsMutable();
+        features_.add(index, value);
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder addFeatures(
+        BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder addFeatures(
+        int index, BaseFeature.Builder builderForValue) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        featuresBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder addAllFeatures(
+        java.lang.Iterable<? extends BaseFeature> values) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, features_);
+        onChanged();
+      } else {
+        featuresBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder clearFeatures() {
+      if (featuresBuilder_ == null) {
+        features_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        featuresBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public Builder removeFeatures(int index) {
+      if (featuresBuilder_ == null) {
+        ensureFeaturesIsMutable();
+        features_.remove(index);
+        onChanged();
+      } else {
+        featuresBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public BaseFeature.Builder getFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public BaseFeatureOrBuilder getFeaturesOrBuilder(
+        int index) {
+      if (featuresBuilder_ == null) {
+        return features_.get(index);  } else {
+        return featuresBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public java.util.List<? extends BaseFeatureOrBuilder>
+         getFeaturesOrBuilderList() {
+      if (featuresBuilder_ != null) {
+        return featuresBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(features_);
+      }
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public BaseFeature.Builder addFeaturesBuilder() {
+      return getFeaturesFieldBuilder().addBuilder(
+          BaseFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public BaseFeature.Builder addFeaturesBuilder(
+        int index) {
+      return getFeaturesFieldBuilder().addBuilder(
+          index, BaseFeature.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .BaseFeature features = 2;</code>
+     */
+    public java.util.List<BaseFeature.Builder>
+         getFeaturesBuilderList() {
+      return getFeaturesFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder>
+        getFeaturesFieldBuilder() {
+      if (featuresBuilder_ == null) {
+        featuresBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+                BaseFeature, BaseFeature.Builder, BaseFeatureOrBuilder>(
+                features_,
+                ((bitField0_ & 0x00000001) != 0),
+                getParentForChildren(),
+                isClean());
+        features_ = null;
+      }
+      return featuresBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:LRWeight)
+  }
+
+  // @@protoc_insertion_point(class_scope:LRWeight)
+  private static final LRWeight DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new LRWeight();
+  }
+
+  public static LRWeight getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<LRWeight>
+      PARSER = new com.google.protobuf.AbstractParser<LRWeight>() {
+    @java.lang.Override
+    public LRWeight parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new LRWeight(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<LRWeight> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<LRWeight> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public LRWeight getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 39 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/LRWeightOrBuilder.java

@@ -0,0 +1,39 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/ctr_samples.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface LRWeightOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:LRWeight)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int32 group_num = 1;</code>
+   * @return The groupNum.
+   */
+  int getGroupNum();
+
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  java.util.List<BaseFeature>
+      getFeaturesList();
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  BaseFeature getFeatures(int index);
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  int getFeaturesCount();
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  java.util.List<? extends BaseFeatureOrBuilder>
+      getFeaturesOrBuilderList();
+  /**
+   * <code>repeated .BaseFeature features = 2;</code>
+   */
+  BaseFeatureOrBuilder getFeaturesOrBuilder(
+      int index);
+}

+ 1387 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/MachineInfoProto.java

@@ -0,0 +1,1387 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code MachineInfoProto}
+ */
+public final class MachineInfoProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:MachineInfoProto)
+    MachineInfoProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use MachineInfoProto.newBuilder() to construct.
+  private MachineInfoProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private MachineInfoProto() {
+    brand_ = "";
+    model_ = "";
+    platform_ = "";
+    sdkVersion_ = "";
+    system_ = "";
+    wechatVersion_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new MachineInfoProto();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private MachineInfoProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            brand_ = s;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            model_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            platform_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            sdkVersion_ = s;
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            system_ = s;
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            wechatVersion_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return Recommend.internal_static_MachineInfoProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return Recommend.internal_static_MachineInfoProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            MachineInfoProto.class, MachineInfoProto.Builder.class);
+  }
+
+  public static final int BRAND_FIELD_NUMBER = 1;
+  private volatile java.lang.Object brand_;
+  /**
+   * <code>string brand = 1;</code>
+   * @return The brand.
+   */
+  @java.lang.Override
+  public java.lang.String getBrand() {
+    java.lang.Object ref = brand_;
+    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();
+      brand_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string brand = 1;</code>
+   * @return The bytes for brand.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getBrandBytes() {
+    java.lang.Object ref = brand_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      brand_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int MODEL_FIELD_NUMBER = 2;
+  private volatile java.lang.Object model_;
+  /**
+   * <pre>
+   * NZA-AL00
+   * </pre>
+   *
+   * <code>string model = 2;</code>
+   * @return The model.
+   */
+  @java.lang.Override
+  public java.lang.String getModel() {
+    java.lang.Object ref = model_;
+    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();
+      model_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * NZA-AL00
+   * </pre>
+   *
+   * <code>string model = 2;</code>
+   * @return The bytes for model.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getModelBytes() {
+    java.lang.Object ref = model_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      model_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PLATFORM_FIELD_NUMBER = 3;
+  private volatile java.lang.Object platform_;
+  /**
+   * <pre>
+   * android
+   * </pre>
+   *
+   * <code>string platform = 3;</code>
+   * @return The platform.
+   */
+  @java.lang.Override
+  public java.lang.String getPlatform() {
+    java.lang.Object ref = platform_;
+    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();
+      platform_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * android
+   * </pre>
+   *
+   * <code>string platform = 3;</code>
+   * @return The bytes for platform.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getPlatformBytes() {
+    java.lang.Object ref = platform_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      platform_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int SDK_VERSION_FIELD_NUMBER = 4;
+  private volatile java.lang.Object sdkVersion_;
+  /**
+   * <pre>
+   * 3.2.4
+   * </pre>
+   *
+   * <code>string sdk_version = 4;</code>
+   * @return The sdkVersion.
+   */
+  @java.lang.Override
+  public java.lang.String getSdkVersion() {
+    java.lang.Object ref = sdkVersion_;
+    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();
+      sdkVersion_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * 3.2.4
+   * </pre>
+   *
+   * <code>string sdk_version = 4;</code>
+   * @return The bytes for sdkVersion.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getSdkVersionBytes() {
+    java.lang.Object ref = sdkVersion_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      sdkVersion_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int SYSTEM_FIELD_NUMBER = 5;
+  private volatile java.lang.Object system_;
+  /**
+   * <pre>
+   * Android 10
+   * </pre>
+   *
+   * <code>string system = 5;</code>
+   * @return The system.
+   */
+  @java.lang.Override
+  public java.lang.String getSystem() {
+    java.lang.Object ref = system_;
+    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();
+      system_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * Android 10
+   * </pre>
+   *
+   * <code>string system = 5;</code>
+   * @return The bytes for system.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getSystemBytes() {
+    java.lang.Object ref = system_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      system_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int WECHAT_VERSION_FIELD_NUMBER = 6;
+  private volatile java.lang.Object wechatVersion_;
+  /**
+   * <pre>
+   * 8.0.43
+   * </pre>
+   *
+   * <code>string wechat_version = 6;</code>
+   * @return The wechatVersion.
+   */
+  @java.lang.Override
+  public java.lang.String getWechatVersion() {
+    java.lang.Object ref = wechatVersion_;
+    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();
+      wechatVersion_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   * 8.0.43
+   * </pre>
+   *
+   * <code>string wechat_version = 6;</code>
+   * @return The bytes for wechatVersion.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getWechatVersionBytes() {
+    java.lang.Object ref = wechatVersion_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      wechatVersion_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getBrandBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, brand_);
+    }
+    if (!getModelBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, model_);
+    }
+    if (!getPlatformBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, platform_);
+    }
+    if (!getSdkVersionBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, sdkVersion_);
+    }
+    if (!getSystemBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, system_);
+    }
+    if (!getWechatVersionBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, wechatVersion_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getBrandBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, brand_);
+    }
+    if (!getModelBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, model_);
+    }
+    if (!getPlatformBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, platform_);
+    }
+    if (!getSdkVersionBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, sdkVersion_);
+    }
+    if (!getSystemBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, system_);
+    }
+    if (!getWechatVersionBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, wechatVersion_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof MachineInfoProto)) {
+      return super.equals(obj);
+    }
+    MachineInfoProto other = (MachineInfoProto) obj;
+
+    if (!getBrand()
+        .equals(other.getBrand())) return false;
+    if (!getModel()
+        .equals(other.getModel())) return false;
+    if (!getPlatform()
+        .equals(other.getPlatform())) return false;
+    if (!getSdkVersion()
+        .equals(other.getSdkVersion())) return false;
+    if (!getSystem()
+        .equals(other.getSystem())) return false;
+    if (!getWechatVersion()
+        .equals(other.getWechatVersion())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + BRAND_FIELD_NUMBER;
+    hash = (53 * hash) + getBrand().hashCode();
+    hash = (37 * hash) + MODEL_FIELD_NUMBER;
+    hash = (53 * hash) + getModel().hashCode();
+    hash = (37 * hash) + PLATFORM_FIELD_NUMBER;
+    hash = (53 * hash) + getPlatform().hashCode();
+    hash = (37 * hash) + SDK_VERSION_FIELD_NUMBER;
+    hash = (53 * hash) + getSdkVersion().hashCode();
+    hash = (37 * hash) + SYSTEM_FIELD_NUMBER;
+    hash = (53 * hash) + getSystem().hashCode();
+    hash = (37 * hash) + WECHAT_VERSION_FIELD_NUMBER;
+    hash = (53 * hash) + getWechatVersion().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static MachineInfoProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static MachineInfoProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static MachineInfoProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static MachineInfoProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static MachineInfoProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static MachineInfoProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static MachineInfoProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static MachineInfoProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static MachineInfoProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static MachineInfoProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static MachineInfoProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static MachineInfoProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(MachineInfoProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code MachineInfoProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:MachineInfoProto)
+          MachineInfoProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return Recommend.internal_static_MachineInfoProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return Recommend.internal_static_MachineInfoProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              MachineInfoProto.class, MachineInfoProto.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.MachineInfoProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      brand_ = "";
+
+      model_ = "";
+
+      platform_ = "";
+
+      sdkVersion_ = "";
+
+      system_ = "";
+
+      wechatVersion_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return Recommend.internal_static_MachineInfoProto_descriptor;
+    }
+
+    @java.lang.Override
+    public MachineInfoProto getDefaultInstanceForType() {
+      return MachineInfoProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public MachineInfoProto build() {
+      MachineInfoProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public MachineInfoProto buildPartial() {
+      MachineInfoProto result = new MachineInfoProto(this);
+      result.brand_ = brand_;
+      result.model_ = model_;
+      result.platform_ = platform_;
+      result.sdkVersion_ = sdkVersion_;
+      result.system_ = system_;
+      result.wechatVersion_ = wechatVersion_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof MachineInfoProto) {
+        return mergeFrom((MachineInfoProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(MachineInfoProto other) {
+      if (other == MachineInfoProto.getDefaultInstance()) return this;
+      if (!other.getBrand().isEmpty()) {
+        brand_ = other.brand_;
+        onChanged();
+      }
+      if (!other.getModel().isEmpty()) {
+        model_ = other.model_;
+        onChanged();
+      }
+      if (!other.getPlatform().isEmpty()) {
+        platform_ = other.platform_;
+        onChanged();
+      }
+      if (!other.getSdkVersion().isEmpty()) {
+        sdkVersion_ = other.sdkVersion_;
+        onChanged();
+      }
+      if (!other.getSystem().isEmpty()) {
+        system_ = other.system_;
+        onChanged();
+      }
+      if (!other.getWechatVersion().isEmpty()) {
+        wechatVersion_ = other.wechatVersion_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      MachineInfoProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (MachineInfoProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object brand_ = "";
+    /**
+     * <code>string brand = 1;</code>
+     * @return The brand.
+     */
+    public java.lang.String getBrand() {
+      java.lang.Object ref = brand_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        brand_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string brand = 1;</code>
+     * @return The bytes for brand.
+     */
+    public com.google.protobuf.ByteString
+        getBrandBytes() {
+      java.lang.Object ref = brand_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        brand_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string brand = 1;</code>
+     * @param value The brand to set.
+     * @return This builder for chaining.
+     */
+    public Builder setBrand(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      brand_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string brand = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearBrand() {
+      
+      brand_ = getDefaultInstance().getBrand();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string brand = 1;</code>
+     * @param value The bytes for brand to set.
+     * @return This builder for chaining.
+     */
+    public Builder setBrandBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      brand_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object model_ = "";
+    /**
+     * <pre>
+     * NZA-AL00
+     * </pre>
+     *
+     * <code>string model = 2;</code>
+     * @return The model.
+     */
+    public java.lang.String getModel() {
+      java.lang.Object ref = model_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        model_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * NZA-AL00
+     * </pre>
+     *
+     * <code>string model = 2;</code>
+     * @return The bytes for model.
+     */
+    public com.google.protobuf.ByteString
+        getModelBytes() {
+      java.lang.Object ref = model_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        model_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * NZA-AL00
+     * </pre>
+     *
+     * <code>string model = 2;</code>
+     * @param value The model to set.
+     * @return This builder for chaining.
+     */
+    public Builder setModel(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      model_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * NZA-AL00
+     * </pre>
+     *
+     * <code>string model = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearModel() {
+      
+      model_ = getDefaultInstance().getModel();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * NZA-AL00
+     * </pre>
+     *
+     * <code>string model = 2;</code>
+     * @param value The bytes for model to set.
+     * @return This builder for chaining.
+     */
+    public Builder setModelBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      model_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object platform_ = "";
+    /**
+     * <pre>
+     * android
+     * </pre>
+     *
+     * <code>string platform = 3;</code>
+     * @return The platform.
+     */
+    public java.lang.String getPlatform() {
+      java.lang.Object ref = platform_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        platform_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * android
+     * </pre>
+     *
+     * <code>string platform = 3;</code>
+     * @return The bytes for platform.
+     */
+    public com.google.protobuf.ByteString
+        getPlatformBytes() {
+      java.lang.Object ref = platform_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        platform_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * android
+     * </pre>
+     *
+     * <code>string platform = 3;</code>
+     * @param value The platform to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPlatform(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      platform_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * android
+     * </pre>
+     *
+     * <code>string platform = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearPlatform() {
+      
+      platform_ = getDefaultInstance().getPlatform();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * android
+     * </pre>
+     *
+     * <code>string platform = 3;</code>
+     * @param value The bytes for platform to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPlatformBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      platform_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object sdkVersion_ = "";
+    /**
+     * <pre>
+     * 3.2.4
+     * </pre>
+     *
+     * <code>string sdk_version = 4;</code>
+     * @return The sdkVersion.
+     */
+    public java.lang.String getSdkVersion() {
+      java.lang.Object ref = sdkVersion_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        sdkVersion_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * 3.2.4
+     * </pre>
+     *
+     * <code>string sdk_version = 4;</code>
+     * @return The bytes for sdkVersion.
+     */
+    public com.google.protobuf.ByteString
+        getSdkVersionBytes() {
+      java.lang.Object ref = sdkVersion_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        sdkVersion_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * 3.2.4
+     * </pre>
+     *
+     * <code>string sdk_version = 4;</code>
+     * @param value The sdkVersion to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSdkVersion(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      sdkVersion_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * 3.2.4
+     * </pre>
+     *
+     * <code>string sdk_version = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearSdkVersion() {
+      
+      sdkVersion_ = getDefaultInstance().getSdkVersion();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * 3.2.4
+     * </pre>
+     *
+     * <code>string sdk_version = 4;</code>
+     * @param value The bytes for sdkVersion to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSdkVersionBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      sdkVersion_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object system_ = "";
+    /**
+     * <pre>
+     * Android 10
+     * </pre>
+     *
+     * <code>string system = 5;</code>
+     * @return The system.
+     */
+    public java.lang.String getSystem() {
+      java.lang.Object ref = system_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        system_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Android 10
+     * </pre>
+     *
+     * <code>string system = 5;</code>
+     * @return The bytes for system.
+     */
+    public com.google.protobuf.ByteString
+        getSystemBytes() {
+      java.lang.Object ref = system_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        system_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * Android 10
+     * </pre>
+     *
+     * <code>string system = 5;</code>
+     * @param value The system to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSystem(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      system_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Android 10
+     * </pre>
+     *
+     * <code>string system = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearSystem() {
+      
+      system_ = getDefaultInstance().getSystem();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * Android 10
+     * </pre>
+     *
+     * <code>string system = 5;</code>
+     * @param value The bytes for system to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSystemBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      system_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object wechatVersion_ = "";
+    /**
+     * <pre>
+     * 8.0.43
+     * </pre>
+     *
+     * <code>string wechat_version = 6;</code>
+     * @return The wechatVersion.
+     */
+    public java.lang.String getWechatVersion() {
+      java.lang.Object ref = wechatVersion_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        wechatVersion_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     * 8.0.43
+     * </pre>
+     *
+     * <code>string wechat_version = 6;</code>
+     * @return The bytes for wechatVersion.
+     */
+    public com.google.protobuf.ByteString
+        getWechatVersionBytes() {
+      java.lang.Object ref = wechatVersion_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        wechatVersion_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     * 8.0.43
+     * </pre>
+     *
+     * <code>string wechat_version = 6;</code>
+     * @param value The wechatVersion to set.
+     * @return This builder for chaining.
+     */
+    public Builder setWechatVersion(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      wechatVersion_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * 8.0.43
+     * </pre>
+     *
+     * <code>string wechat_version = 6;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearWechatVersion() {
+      
+      wechatVersion_ = getDefaultInstance().getWechatVersion();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * 8.0.43
+     * </pre>
+     *
+     * <code>string wechat_version = 6;</code>
+     * @param value The bytes for wechatVersion to set.
+     * @return This builder for chaining.
+     */
+    public Builder setWechatVersionBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      wechatVersion_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:MachineInfoProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:MachineInfoProto)
+  private static final MachineInfoProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new MachineInfoProto();
+  }
+
+  public static MachineInfoProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<MachineInfoProto>
+      PARSER = new com.google.protobuf.AbstractParser<MachineInfoProto>() {
+    @java.lang.Override
+    public MachineInfoProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new MachineInfoProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<MachineInfoProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<MachineInfoProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public MachineInfoProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 121 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/MachineInfoProtoOrBuilder.java

@@ -0,0 +1,121 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface MachineInfoProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:MachineInfoProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string brand = 1;</code>
+   * @return The brand.
+   */
+  java.lang.String getBrand();
+  /**
+   * <code>string brand = 1;</code>
+   * @return The bytes for brand.
+   */
+  com.google.protobuf.ByteString
+      getBrandBytes();
+
+  /**
+   * <pre>
+   * NZA-AL00
+   * </pre>
+   *
+   * <code>string model = 2;</code>
+   * @return The model.
+   */
+  java.lang.String getModel();
+  /**
+   * <pre>
+   * NZA-AL00
+   * </pre>
+   *
+   * <code>string model = 2;</code>
+   * @return The bytes for model.
+   */
+  com.google.protobuf.ByteString
+      getModelBytes();
+
+  /**
+   * <pre>
+   * android
+   * </pre>
+   *
+   * <code>string platform = 3;</code>
+   * @return The platform.
+   */
+  java.lang.String getPlatform();
+  /**
+   * <pre>
+   * android
+   * </pre>
+   *
+   * <code>string platform = 3;</code>
+   * @return The bytes for platform.
+   */
+  com.google.protobuf.ByteString
+      getPlatformBytes();
+
+  /**
+   * <pre>
+   * 3.2.4
+   * </pre>
+   *
+   * <code>string sdk_version = 4;</code>
+   * @return The sdkVersion.
+   */
+  java.lang.String getSdkVersion();
+  /**
+   * <pre>
+   * 3.2.4
+   * </pre>
+   *
+   * <code>string sdk_version = 4;</code>
+   * @return The bytes for sdkVersion.
+   */
+  com.google.protobuf.ByteString
+      getSdkVersionBytes();
+
+  /**
+   * <pre>
+   * Android 10
+   * </pre>
+   *
+   * <code>string system = 5;</code>
+   * @return The system.
+   */
+  java.lang.String getSystem();
+  /**
+   * <pre>
+   * Android 10
+   * </pre>
+   *
+   * <code>string system = 5;</code>
+   * @return The bytes for system.
+   */
+  com.google.protobuf.ByteString
+      getSystemBytes();
+
+  /**
+   * <pre>
+   * 8.0.43
+   * </pre>
+   *
+   * <code>string wechat_version = 6;</code>
+   * @return The wechatVersion.
+   */
+  java.lang.String getWechatVersion();
+  /**
+   * <pre>
+   * 8.0.43
+   * </pre>
+   *
+   * <code>string wechat_version = 6;</code>
+   * @return The bytes for wechatVersion.
+   */
+  com.google.protobuf.ByteString
+      getWechatVersionBytes();
+}

+ 122 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/Recommend.java

@@ -0,0 +1,122 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public final class Recommend {
+  private Recommend() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_RecommendRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_RecommendRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_RecommendRequest_EventIdEntry_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_RecommendRequest_EventIdEntry_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_MachineInfoProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_MachineInfoProto_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_RecommendResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_RecommendResponse_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_VideoProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_VideoProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n2com/tzld/piaoquan/recommend/server/rec" +
+      "ommend.proto\032\031google/protobuf/any.proto\032" +
+      "/com/tzld/piaoquan/recommend/server/comm" +
+      "on.proto\"\226\003\n\020RecommendRequest\022\022\n\nrequest" +
+      "_id\030\001 \001(\t\022\013\n\003mid\030\002 \001(\t\022\013\n\003uid\030\003 \001(\t\022\014\n\004s" +
+      "ize\030\004 \001(\005\022\020\n\010app_type\030\005 \001(\005\022\021\n\tcity_code" +
+      "\030\006 \001(\t\022\025\n\rprovince_code\030\007 \001(\t\022\023\n\013ab_exp_" +
+      "code\030\010 \003(\t\0220\n\010event_id\030\t \003(\0132\036.Recommend" +
+      "Request.EventIdEntry\022\034\n\024version_audit_st" +
+      "atus\030\n \001(\005\022\032\n\022recommend_trace_id\030\013 \001(\t\022\020" +
+      "\n\010video_id\030\014 \001(\003\022\014\n\004city\030\r \001(\t\022\020\n\010provin" +
+      "ce\030\016 \001(\t\022\'\n\014machine_info\030\017 \001(\0132\021.Machine" +
+      "InfoProto\032.\n\014EventIdEntry\022\013\n\003key\030\001 \001(\t\022\r" +
+      "\n\005value\030\002 \001(\t:\0028\001\"\177\n\020MachineInfoProto\022\r\n" +
+      "\005brand\030\001 \001(\t\022\r\n\005model\030\002 \001(\t\022\020\n\010platform\030" +
+      "\003 \001(\t\022\023\n\013sdk_version\030\004 \001(\t\022\016\n\006system\030\005 \001" +
+      "(\t\022\026\n\016wechat_version\030\006 \001(\t\"H\n\021RecommendR" +
+      "esponse\022\027\n\006result\030\001 \001(\0132\007.Result\022\032\n\005vide" +
+      "o\030\002 \003(\0132\013.VideoProto\"\265\001\n\nVideoProto\022\020\n\010v" +
+      "ideo_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_sco" +
+      "re\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\212\001\n\020RecommendService\022:\n\021HomepageRec" +
+      "ommend\022\021.RecommendRequest\032\022.RecommendRes" +
+      "ponse\022:\n\021RelevantRecommend\022\021.RecommendRe" +
+      "quest\032\022.RecommendResponseB7\n0com.tzld.pi" +
+      "aoquan.recommend.server.gen.recommendP\001\210" +
+      "\001\001b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          com.google.protobuf.AnyProto.getDescriptor(),
+          com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor(),
+        });
+    internal_static_RecommendRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_RecommendRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_RecommendRequest_descriptor,
+        new java.lang.String[] { "RequestId", "Mid", "Uid", "Size", "AppType", "CityCode", "ProvinceCode", "AbExpCode", "EventId", "VersionAuditStatus", "RecommendTraceId", "VideoId", "City", "Province", "MachineInfo", });
+    internal_static_RecommendRequest_EventIdEntry_descriptor =
+      internal_static_RecommendRequest_descriptor.getNestedTypes().get(0);
+    internal_static_RecommendRequest_EventIdEntry_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_RecommendRequest_EventIdEntry_descriptor,
+        new java.lang.String[] { "Key", "Value", });
+    internal_static_MachineInfoProto_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_MachineInfoProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_MachineInfoProto_descriptor,
+        new java.lang.String[] { "Brand", "Model", "Platform", "SdkVersion", "System", "WechatVersion", });
+    internal_static_RecommendResponse_descriptor =
+      getDescriptor().getMessageTypes().get(2);
+    internal_static_RecommendResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_RecommendResponse_descriptor,
+        new java.lang.String[] { "Result", "Video", });
+    internal_static_VideoProto_descriptor =
+      getDescriptor().getMessageTypes().get(3);
+    internal_static_VideoProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_VideoProto_descriptor,
+        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();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

+ 2494 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendRequest.java

@@ -0,0 +1,2494 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf type {@code RecommendRequest}
+ */
+public final class RecommendRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:RecommendRequest)
+    RecommendRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RecommendRequest.newBuilder() to construct.
+  private RecommendRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RecommendRequest() {
+    requestId_ = "";
+    mid_ = "";
+    uid_ = "";
+    cityCode_ = "";
+    provinceCode_ = "";
+    abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    recommendTraceId_ = "";
+    city_ = "";
+    province_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new RecommendRequest();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RecommendRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            requestId_ = s;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            mid_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            uid_ = s;
+            break;
+          }
+          case 32: {
+
+            size_ = input.readInt32();
+            break;
+          }
+          case 40: {
+
+            appType_ = input.readInt32();
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            cityCode_ = s;
+            break;
+          }
+          case 58: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            provinceCode_ = s;
+            break;
+          }
+          case 66: {
+            java.lang.String s = input.readStringRequireUtf8();
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              abExpCode_ = new com.google.protobuf.LazyStringArrayList();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            abExpCode_.add(s);
+            break;
+          }
+          case 74: {
+            if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+              eventId_ = com.google.protobuf.MapField.newMapField(
+                  EventIdDefaultEntryHolder.defaultEntry);
+              mutable_bitField0_ |= 0x00000002;
+            }
+            com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
+            eventId__ = input.readMessage(
+                EventIdDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
+            eventId_.getMutableMap().put(
+                eventId__.getKey(), eventId__.getValue());
+            break;
+          }
+          case 80: {
+
+            versionAuditStatus_ = input.readInt32();
+            break;
+          }
+          case 90: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            recommendTraceId_ = s;
+            break;
+          }
+          case 96: {
+
+            videoId_ = input.readInt64();
+            break;
+          }
+          case 106: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            city_ = s;
+            break;
+          }
+          case 114: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            province_ = s;
+            break;
+          }
+          case 122: {
+            MachineInfoProto.Builder subBuilder = null;
+            if (machineInfo_ != null) {
+              subBuilder = machineInfo_.toBuilder();
+            }
+            machineInfo_ = input.readMessage(MachineInfoProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(machineInfo_);
+              machineInfo_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = abExpCode_.getUnmodifiableView();
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return Recommend.internal_static_RecommendRequest_descriptor;
+  }
+
+  @SuppressWarnings({"rawtypes"})
+  @java.lang.Override
+  protected com.google.protobuf.MapField internalGetMapField(
+      int number) {
+    switch (number) {
+      case 9:
+        return internalGetEventId();
+      default:
+        throw new RuntimeException(
+            "Invalid map field number: " + number);
+    }
+  }
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return Recommend.internal_static_RecommendRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            RecommendRequest.class, RecommendRequest.Builder.class);
+  }
+
+  public static final int REQUEST_ID_FIELD_NUMBER = 1;
+  private volatile java.lang.Object requestId_;
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The requestId.
+   */
+  @java.lang.Override
+  public java.lang.String getRequestId() {
+    java.lang.Object ref = requestId_;
+    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();
+      requestId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The bytes for requestId.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getRequestIdBytes() {
+    java.lang.Object ref = requestId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      requestId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int MID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object mid_;
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  @java.lang.Override
+  public java.lang.String getMid() {
+    java.lang.Object ref = mid_;
+    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();
+      mid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getMidBytes() {
+    java.lang.Object ref = mid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      mid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int UID_FIELD_NUMBER = 3;
+  private volatile java.lang.Object uid_;
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  @java.lang.Override
+  public java.lang.String getUid() {
+    java.lang.Object ref = uid_;
+    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();
+      uid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getUidBytes() {
+    java.lang.Object ref = uid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      uid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int SIZE_FIELD_NUMBER = 4;
+  private int size_;
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 size = 4;</code>
+   * @return The size.
+   */
+  @java.lang.Override
+  public int getSize() {
+    return size_;
+  }
+
+  public static final int APP_TYPE_FIELD_NUMBER = 5;
+  private int appType_;
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 app_type = 5;</code>
+   * @return The appType.
+   */
+  @java.lang.Override
+  public int getAppType() {
+    return appType_;
+  }
+
+  public static final int CITY_CODE_FIELD_NUMBER = 6;
+  private volatile java.lang.Object cityCode_;
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The cityCode.
+   */
+  @java.lang.Override
+  public java.lang.String getCityCode() {
+    java.lang.Object ref = cityCode_;
+    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();
+      cityCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The bytes for cityCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCityCodeBytes() {
+    java.lang.Object ref = cityCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      cityCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PROVINCE_CODE_FIELD_NUMBER = 7;
+  private volatile java.lang.Object provinceCode_;
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The provinceCode.
+   */
+  @java.lang.Override
+  public java.lang.String getProvinceCode() {
+    java.lang.Object ref = provinceCode_;
+    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();
+      provinceCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The bytes for provinceCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getProvinceCodeBytes() {
+    java.lang.Object ref = provinceCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      provinceCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int AB_EXP_CODE_FIELD_NUMBER = 8;
+  private com.google.protobuf.LazyStringList abExpCode_;
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @return A list containing the abExpCode.
+   */
+  public com.google.protobuf.ProtocolStringList
+      getAbExpCodeList() {
+    return abExpCode_;
+  }
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @return The count of abExpCode.
+   */
+  public int getAbExpCodeCount() {
+    return abExpCode_.size();
+  }
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @param index The index of the element to return.
+   * @return The abExpCode at the given index.
+   */
+  public java.lang.String getAbExpCode(int index) {
+    return abExpCode_.get(index);
+  }
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @param index The index of the value to return.
+   * @return The bytes of the abExpCode at the given index.
+   */
+  public com.google.protobuf.ByteString
+      getAbExpCodeBytes(int index) {
+    return abExpCode_.getByteString(index);
+  }
+
+  public static final int EVENT_ID_FIELD_NUMBER = 9;
+  private static final class EventIdDefaultEntryHolder {
+    static final com.google.protobuf.MapEntry<
+        java.lang.String, java.lang.String> defaultEntry =
+            com.google.protobuf.MapEntry
+            .<java.lang.String, java.lang.String>newDefaultInstance(
+                Recommend.internal_static_RecommendRequest_EventIdEntry_descriptor,
+                com.google.protobuf.WireFormat.FieldType.STRING,
+                "",
+                com.google.protobuf.WireFormat.FieldType.STRING,
+                "");
+  }
+  private com.google.protobuf.MapField<
+      java.lang.String, java.lang.String> eventId_;
+  private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+  internalGetEventId() {
+    if (eventId_ == null) {
+      return com.google.protobuf.MapField.emptyMapField(
+          EventIdDefaultEntryHolder.defaultEntry);
+    }
+    return eventId_;
+  }
+
+  public int getEventIdCount() {
+    return internalGetEventId().getMap().size();
+  }
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+
+  @java.lang.Override
+  public boolean containsEventId(
+      java.lang.String key) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    return internalGetEventId().getMap().containsKey(key);
+  }
+  /**
+   * Use {@link #getEventIdMap()} instead.
+   */
+  @java.lang.Override
+  @java.lang.Deprecated
+  public java.util.Map<java.lang.String, java.lang.String> getEventId() {
+    return getEventIdMap();
+  }
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  @java.lang.Override
+
+  public java.util.Map<java.lang.String, java.lang.String> getEventIdMap() {
+    return internalGetEventId().getMap();
+  }
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  @java.lang.Override
+
+  public java.lang.String getEventIdOrDefault(
+      java.lang.String key,
+      java.lang.String defaultValue) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    java.util.Map<java.lang.String, java.lang.String> map =
+        internalGetEventId().getMap();
+    return map.containsKey(key) ? map.get(key) : defaultValue;
+  }
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  @java.lang.Override
+
+  public java.lang.String getEventIdOrThrow(
+      java.lang.String key) {
+    if (key == null) { throw new java.lang.NullPointerException(); }
+    java.util.Map<java.lang.String, java.lang.String> map =
+        internalGetEventId().getMap();
+    if (!map.containsKey(key)) {
+      throw new java.lang.IllegalArgumentException();
+    }
+    return map.get(key);
+  }
+
+  public static final int VERSION_AUDIT_STATUS_FIELD_NUMBER = 10;
+  private int versionAuditStatus_;
+  /**
+   * <pre>
+   * default 2
+   * </pre>
+   *
+   * <code>int32 version_audit_status = 10;</code>
+   * @return The versionAuditStatus.
+   */
+  @java.lang.Override
+  public int getVersionAuditStatus() {
+    return versionAuditStatus_;
+  }
+
+  public static final int RECOMMEND_TRACE_ID_FIELD_NUMBER = 11;
+  private volatile java.lang.Object recommendTraceId_;
+  /**
+   * <code>string recommend_trace_id = 11;</code>
+   * @return The recommendTraceId.
+   */
+  @java.lang.Override
+  public java.lang.String getRecommendTraceId() {
+    java.lang.Object ref = recommendTraceId_;
+    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();
+      recommendTraceId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string recommend_trace_id = 11;</code>
+   * @return The bytes for recommendTraceId.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getRecommendTraceIdBytes() {
+    java.lang.Object ref = recommendTraceId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      recommendTraceId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int VIDEO_ID_FIELD_NUMBER = 12;
+  private long videoId_;
+  /**
+   * <code>int64 video_id = 12;</code>
+   * @return The videoId.
+   */
+  @java.lang.Override
+  public long getVideoId() {
+    return videoId_;
+  }
+
+  public static final int CITY_FIELD_NUMBER = 13;
+  private volatile java.lang.Object city_;
+  /**
+   * <code>string city = 13;</code>
+   * @return The city.
+   */
+  @java.lang.Override
+  public java.lang.String getCity() {
+    java.lang.Object ref = city_;
+    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();
+      city_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string city = 13;</code>
+   * @return The bytes for city.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCityBytes() {
+    java.lang.Object ref = city_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      city_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PROVINCE_FIELD_NUMBER = 14;
+  private volatile java.lang.Object province_;
+  /**
+   * <code>string province = 14;</code>
+   * @return The province.
+   */
+  @java.lang.Override
+  public java.lang.String getProvince() {
+    java.lang.Object ref = province_;
+    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();
+      province_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string province = 14;</code>
+   * @return The bytes for province.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getProvinceBytes() {
+    java.lang.Object ref = province_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      province_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int MACHINE_INFO_FIELD_NUMBER = 15;
+  private MachineInfoProto machineInfo_;
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   * @return Whether the machineInfo field is set.
+   */
+  @java.lang.Override
+  public boolean hasMachineInfo() {
+    return machineInfo_ != null;
+  }
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   * @return The machineInfo.
+   */
+  @java.lang.Override
+  public MachineInfoProto getMachineInfo() {
+    return machineInfo_ == null ? MachineInfoProto.getDefaultInstance() : machineInfo_;
+  }
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   */
+  @java.lang.Override
+  public MachineInfoProtoOrBuilder getMachineInfoOrBuilder() {
+    return getMachineInfo();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getRequestIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, requestId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, uid_);
+    }
+    if (size_ != 0) {
+      output.writeInt32(4, size_);
+    }
+    if (appType_ != 0) {
+      output.writeInt32(5, appType_);
+    }
+    if (!getCityCodeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, cityCode_);
+    }
+    if (!getProvinceCodeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 7, provinceCode_);
+    }
+    for (int i = 0; i < abExpCode_.size(); i++) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 8, abExpCode_.getRaw(i));
+    }
+    com.google.protobuf.GeneratedMessageV3
+      .serializeStringMapTo(
+        output,
+        internalGetEventId(),
+        EventIdDefaultEntryHolder.defaultEntry,
+        9);
+    if (versionAuditStatus_ != 0) {
+      output.writeInt32(10, versionAuditStatus_);
+    }
+    if (!getRecommendTraceIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 11, recommendTraceId_);
+    }
+    if (videoId_ != 0L) {
+      output.writeInt64(12, videoId_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 13, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 14, province_);
+    }
+    if (machineInfo_ != null) {
+      output.writeMessage(15, getMachineInfo());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getRequestIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, requestId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, uid_);
+    }
+    if (size_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(4, size_);
+    }
+    if (appType_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(5, appType_);
+    }
+    if (!getCityCodeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, cityCode_);
+    }
+    if (!getProvinceCodeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, provinceCode_);
+    }
+    {
+      int dataSize = 0;
+      for (int i = 0; i < abExpCode_.size(); i++) {
+        dataSize += computeStringSizeNoTag(abExpCode_.getRaw(i));
+      }
+      size += dataSize;
+      size += 1 * getAbExpCodeList().size();
+    }
+    for (java.util.Map.Entry<java.lang.String, java.lang.String> entry
+         : internalGetEventId().getMap().entrySet()) {
+      com.google.protobuf.MapEntry<java.lang.String, java.lang.String>
+      eventId__ = EventIdDefaultEntryHolder.defaultEntry.newBuilderForType()
+          .setKey(entry.getKey())
+          .setValue(entry.getValue())
+          .build();
+      size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(9, eventId__);
+    }
+    if (versionAuditStatus_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(10, versionAuditStatus_);
+    }
+    if (!getRecommendTraceIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, recommendTraceId_);
+    }
+    if (videoId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(12, videoId_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, province_);
+    }
+    if (machineInfo_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(15, getMachineInfo());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof RecommendRequest)) {
+      return super.equals(obj);
+    }
+    RecommendRequest other = (RecommendRequest) obj;
+
+    if (!getRequestId()
+        .equals(other.getRequestId())) return false;
+    if (!getMid()
+        .equals(other.getMid())) return false;
+    if (!getUid()
+        .equals(other.getUid())) return false;
+    if (getSize()
+        != other.getSize()) return false;
+    if (getAppType()
+        != other.getAppType()) return false;
+    if (!getCityCode()
+        .equals(other.getCityCode())) return false;
+    if (!getProvinceCode()
+        .equals(other.getProvinceCode())) return false;
+    if (!getAbExpCodeList()
+        .equals(other.getAbExpCodeList())) return false;
+    if (!internalGetEventId().equals(
+        other.internalGetEventId())) return false;
+    if (getVersionAuditStatus()
+        != other.getVersionAuditStatus()) return false;
+    if (!getRecommendTraceId()
+        .equals(other.getRecommendTraceId())) return false;
+    if (getVideoId()
+        != other.getVideoId()) return false;
+    if (!getCity()
+        .equals(other.getCity())) return false;
+    if (!getProvince()
+        .equals(other.getProvince())) return false;
+    if (hasMachineInfo() != other.hasMachineInfo()) return false;
+    if (hasMachineInfo()) {
+      if (!getMachineInfo()
+          .equals(other.getMachineInfo())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + REQUEST_ID_FIELD_NUMBER;
+    hash = (53 * hash) + getRequestId().hashCode();
+    hash = (37 * hash) + MID_FIELD_NUMBER;
+    hash = (53 * hash) + getMid().hashCode();
+    hash = (37 * hash) + UID_FIELD_NUMBER;
+    hash = (53 * hash) + getUid().hashCode();
+    hash = (37 * hash) + SIZE_FIELD_NUMBER;
+    hash = (53 * hash) + getSize();
+    hash = (37 * hash) + APP_TYPE_FIELD_NUMBER;
+    hash = (53 * hash) + getAppType();
+    hash = (37 * hash) + CITY_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getCityCode().hashCode();
+    hash = (37 * hash) + PROVINCE_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getProvinceCode().hashCode();
+    if (getAbExpCodeCount() > 0) {
+      hash = (37 * hash) + AB_EXP_CODE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbExpCodeList().hashCode();
+    }
+    if (!internalGetEventId().getMap().isEmpty()) {
+      hash = (37 * hash) + EVENT_ID_FIELD_NUMBER;
+      hash = (53 * hash) + internalGetEventId().hashCode();
+    }
+    hash = (37 * hash) + VERSION_AUDIT_STATUS_FIELD_NUMBER;
+    hash = (53 * hash) + getVersionAuditStatus();
+    hash = (37 * hash) + RECOMMEND_TRACE_ID_FIELD_NUMBER;
+    hash = (53 * hash) + getRecommendTraceId().hashCode();
+    hash = (37 * hash) + VIDEO_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getVideoId());
+    hash = (37 * hash) + CITY_FIELD_NUMBER;
+    hash = (53 * hash) + getCity().hashCode();
+    hash = (37 * hash) + PROVINCE_FIELD_NUMBER;
+    hash = (53 * hash) + getProvince().hashCode();
+    if (hasMachineInfo()) {
+      hash = (37 * hash) + MACHINE_INFO_FIELD_NUMBER;
+      hash = (53 * hash) + getMachineInfo().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static RecommendRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static RecommendRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static RecommendRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static RecommendRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static RecommendRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static RecommendRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(RecommendRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code RecommendRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:RecommendRequest)
+          RecommendRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return Recommend.internal_static_RecommendRequest_descriptor;
+    }
+
+    @SuppressWarnings({"rawtypes"})
+    protected com.google.protobuf.MapField internalGetMapField(
+        int number) {
+      switch (number) {
+        case 9:
+          return internalGetEventId();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    @SuppressWarnings({"rawtypes"})
+    protected com.google.protobuf.MapField internalGetMutableMapField(
+        int number) {
+      switch (number) {
+        case 9:
+          return internalGetMutableEventId();
+        default:
+          throw new RuntimeException(
+              "Invalid map field number: " + number);
+      }
+    }
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return Recommend.internal_static_RecommendRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              RecommendRequest.class, RecommendRequest.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.RecommendRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      requestId_ = "";
+
+      mid_ = "";
+
+      uid_ = "";
+
+      size_ = 0;
+
+      appType_ = 0;
+
+      cityCode_ = "";
+
+      provinceCode_ = "";
+
+      abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      bitField0_ = (bitField0_ & ~0x00000001);
+      internalGetMutableEventId().clear();
+      versionAuditStatus_ = 0;
+
+      recommendTraceId_ = "";
+
+      videoId_ = 0L;
+
+      city_ = "";
+
+      province_ = "";
+
+      if (machineInfoBuilder_ == null) {
+        machineInfo_ = null;
+      } else {
+        machineInfo_ = null;
+        machineInfoBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return Recommend.internal_static_RecommendRequest_descriptor;
+    }
+
+    @java.lang.Override
+    public RecommendRequest getDefaultInstanceForType() {
+      return RecommendRequest.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public RecommendRequest build() {
+      RecommendRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public RecommendRequest buildPartial() {
+      RecommendRequest result = new RecommendRequest(this);
+      int from_bitField0_ = bitField0_;
+      result.requestId_ = requestId_;
+      result.mid_ = mid_;
+      result.uid_ = uid_;
+      result.size_ = size_;
+      result.appType_ = appType_;
+      result.cityCode_ = cityCode_;
+      result.provinceCode_ = provinceCode_;
+      if (((bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = abExpCode_.getUnmodifiableView();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      }
+      result.abExpCode_ = abExpCode_;
+      result.eventId_ = internalGetEventId();
+      result.eventId_.makeImmutable();
+      result.versionAuditStatus_ = versionAuditStatus_;
+      result.recommendTraceId_ = recommendTraceId_;
+      result.videoId_ = videoId_;
+      result.city_ = city_;
+      result.province_ = province_;
+      if (machineInfoBuilder_ == null) {
+        result.machineInfo_ = machineInfo_;
+      } else {
+        result.machineInfo_ = machineInfoBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof RecommendRequest) {
+        return mergeFrom((RecommendRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(RecommendRequest other) {
+      if (other == RecommendRequest.getDefaultInstance()) return this;
+      if (!other.getRequestId().isEmpty()) {
+        requestId_ = other.requestId_;
+        onChanged();
+      }
+      if (!other.getMid().isEmpty()) {
+        mid_ = other.mid_;
+        onChanged();
+      }
+      if (!other.getUid().isEmpty()) {
+        uid_ = other.uid_;
+        onChanged();
+      }
+      if (other.getSize() != 0) {
+        setSize(other.getSize());
+      }
+      if (other.getAppType() != 0) {
+        setAppType(other.getAppType());
+      }
+      if (!other.getCityCode().isEmpty()) {
+        cityCode_ = other.cityCode_;
+        onChanged();
+      }
+      if (!other.getProvinceCode().isEmpty()) {
+        provinceCode_ = other.provinceCode_;
+        onChanged();
+      }
+      if (!other.abExpCode_.isEmpty()) {
+        if (abExpCode_.isEmpty()) {
+          abExpCode_ = other.abExpCode_;
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          ensureAbExpCodeIsMutable();
+          abExpCode_.addAll(other.abExpCode_);
+        }
+        onChanged();
+      }
+      internalGetMutableEventId().mergeFrom(
+          other.internalGetEventId());
+      if (other.getVersionAuditStatus() != 0) {
+        setVersionAuditStatus(other.getVersionAuditStatus());
+      }
+      if (!other.getRecommendTraceId().isEmpty()) {
+        recommendTraceId_ = other.recommendTraceId_;
+        onChanged();
+      }
+      if (other.getVideoId() != 0L) {
+        setVideoId(other.getVideoId());
+      }
+      if (!other.getCity().isEmpty()) {
+        city_ = other.city_;
+        onChanged();
+      }
+      if (!other.getProvince().isEmpty()) {
+        province_ = other.province_;
+        onChanged();
+      }
+      if (other.hasMachineInfo()) {
+        mergeMachineInfo(other.getMachineInfo());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      RecommendRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (RecommendRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private java.lang.Object requestId_ = "";
+    /**
+     * <code>string request_id = 1;</code>
+     * @return The requestId.
+     */
+    public java.lang.String getRequestId() {
+      java.lang.Object ref = requestId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        requestId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @return The bytes for requestId.
+     */
+    public com.google.protobuf.ByteString
+        getRequestIdBytes() {
+      java.lang.Object ref = requestId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        requestId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @param value The requestId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRequestId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      requestId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRequestId() {
+      
+      requestId_ = getDefaultInstance().getRequestId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @param value The bytes for requestId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRequestIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      requestId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object mid_ = "";
+    /**
+     * <code>string mid = 2;</code>
+     * @return The mid.
+     */
+    public java.lang.String getMid() {
+      java.lang.Object ref = mid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        mid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return The bytes for mid.
+     */
+    public com.google.protobuf.ByteString
+        getMidBytes() {
+      java.lang.Object ref = mid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        mid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearMid() {
+      
+      mid_ = getDefaultInstance().getMid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The bytes for mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object uid_ = "";
+    /**
+     * <code>string uid = 3;</code>
+     * @return The uid.
+     */
+    public java.lang.String getUid() {
+      java.lang.Object ref = uid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        uid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return The bytes for uid.
+     */
+    public com.google.protobuf.ByteString
+        getUidBytes() {
+      java.lang.Object ref = uid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        uid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearUid() {
+      
+      uid_ = getDefaultInstance().getUid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The bytes for uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int size_ ;
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 size = 4;</code>
+     * @return The size.
+     */
+    @java.lang.Override
+    public int getSize() {
+      return size_;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 size = 4;</code>
+     * @param value The size to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSize(int value) {
+      
+      size_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 size = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearSize() {
+      
+      size_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private int appType_ ;
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 5;</code>
+     * @return The appType.
+     */
+    @java.lang.Override
+    public int getAppType() {
+      return appType_;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 5;</code>
+     * @param value The appType to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAppType(int value) {
+      
+      appType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearAppType() {
+      
+      appType_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object cityCode_ = "";
+    /**
+     * <code>string city_code = 6;</code>
+     * @return The cityCode.
+     */
+    public java.lang.String getCityCode() {
+      java.lang.Object ref = cityCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        cityCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @return The bytes for cityCode.
+     */
+    public com.google.protobuf.ByteString
+        getCityCodeBytes() {
+      java.lang.Object ref = cityCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        cityCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @param value The cityCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      cityCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCityCode() {
+      
+      cityCode_ = getDefaultInstance().getCityCode();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @param value The bytes for cityCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      cityCode_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object provinceCode_ = "";
+    /**
+     * <code>string province_code = 7;</code>
+     * @return The provinceCode.
+     */
+    public java.lang.String getProvinceCode() {
+      java.lang.Object ref = provinceCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        provinceCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @return The bytes for provinceCode.
+     */
+    public com.google.protobuf.ByteString
+        getProvinceCodeBytes() {
+      java.lang.Object ref = provinceCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        provinceCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @param value The provinceCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      provinceCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearProvinceCode() {
+      
+      provinceCode_ = getDefaultInstance().getProvinceCode();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @param value The bytes for provinceCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      provinceCode_ = value;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.LazyStringList abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    private void ensureAbExpCodeIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = new com.google.protobuf.LazyStringArrayList(abExpCode_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @return A list containing the abExpCode.
+     */
+    public com.google.protobuf.ProtocolStringList
+        getAbExpCodeList() {
+      return abExpCode_.getUnmodifiableView();
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @return The count of abExpCode.
+     */
+    public int getAbExpCodeCount() {
+      return abExpCode_.size();
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param index The index of the element to return.
+     * @return The abExpCode at the given index.
+     */
+    public java.lang.String getAbExpCode(int index) {
+      return abExpCode_.get(index);
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param index The index of the value to return.
+     * @return The bytes of the abExpCode at the given index.
+     */
+    public com.google.protobuf.ByteString
+        getAbExpCodeBytes(int index) {
+      return abExpCode_.getByteString(index);
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param index The index to set the value at.
+     * @param value The abExpCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAbExpCode(
+        int index, java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureAbExpCodeIsMutable();
+      abExpCode_.set(index, value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param value The abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAbExpCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureAbExpCodeIsMutable();
+      abExpCode_.add(value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param values The abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAllAbExpCode(
+        java.lang.Iterable<java.lang.String> values) {
+      ensureAbExpCodeIsMutable();
+      com.google.protobuf.AbstractMessageLite.Builder.addAll(
+          values, abExpCode_);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearAbExpCode() {
+      abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      bitField0_ = (bitField0_ & ~0x00000001);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 8;</code>
+     * @param value The bytes of the abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAbExpCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      ensureAbExpCodeIsMutable();
+      abExpCode_.add(value);
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.MapField<
+        java.lang.String, java.lang.String> eventId_;
+    private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+    internalGetEventId() {
+      if (eventId_ == null) {
+        return com.google.protobuf.MapField.emptyMapField(
+            EventIdDefaultEntryHolder.defaultEntry);
+      }
+      return eventId_;
+    }
+    private com.google.protobuf.MapField<java.lang.String, java.lang.String>
+    internalGetMutableEventId() {
+      onChanged();;
+      if (eventId_ == null) {
+        eventId_ = com.google.protobuf.MapField.newMapField(
+            EventIdDefaultEntryHolder.defaultEntry);
+      }
+      if (!eventId_.isMutable()) {
+        eventId_ = eventId_.copy();
+      }
+      return eventId_;
+    }
+
+    public int getEventIdCount() {
+      return internalGetEventId().getMap().size();
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+
+    @java.lang.Override
+    public boolean containsEventId(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      return internalGetEventId().getMap().containsKey(key);
+    }
+    /**
+     * Use {@link #getEventIdMap()} instead.
+     */
+    @java.lang.Override
+    @java.lang.Deprecated
+    public java.util.Map<java.lang.String, java.lang.String> getEventId() {
+      return getEventIdMap();
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+    @java.lang.Override
+
+    public java.util.Map<java.lang.String, java.lang.String> getEventIdMap() {
+      return internalGetEventId().getMap();
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+    @java.lang.Override
+
+    public java.lang.String getEventIdOrDefault(
+        java.lang.String key,
+        java.lang.String defaultValue) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      java.util.Map<java.lang.String, java.lang.String> map =
+          internalGetEventId().getMap();
+      return map.containsKey(key) ? map.get(key) : defaultValue;
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+    @java.lang.Override
+
+    public java.lang.String getEventIdOrThrow(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      java.util.Map<java.lang.String, java.lang.String> map =
+          internalGetEventId().getMap();
+      if (!map.containsKey(key)) {
+        throw new java.lang.IllegalArgumentException();
+      }
+      return map.get(key);
+    }
+
+    public Builder clearEventId() {
+      internalGetMutableEventId().getMutableMap()
+          .clear();
+      return this;
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+
+    public Builder removeEventId(
+        java.lang.String key) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      internalGetMutableEventId().getMutableMap()
+          .remove(key);
+      return this;
+    }
+    /**
+     * Use alternate mutation accessors instead.
+     */
+    @java.lang.Deprecated
+    public java.util.Map<java.lang.String, java.lang.String>
+    getMutableEventId() {
+      return internalGetMutableEventId().getMutableMap();
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+    public Builder putEventId(
+        java.lang.String key,
+        java.lang.String value) {
+      if (key == null) { throw new java.lang.NullPointerException(); }
+      if (value == null) { throw new java.lang.NullPointerException(); }
+      internalGetMutableEventId().getMutableMap()
+          .put(key, value);
+      return this;
+    }
+    /**
+     * <code>map&lt;string, string&gt; event_id = 9;</code>
+     */
+
+    public Builder putAllEventId(
+        java.util.Map<java.lang.String, java.lang.String> values) {
+      internalGetMutableEventId().getMutableMap()
+          .putAll(values);
+      return this;
+    }
+
+    private int versionAuditStatus_ ;
+    /**
+     * <pre>
+     * default 2
+     * </pre>
+     *
+     * <code>int32 version_audit_status = 10;</code>
+     * @return The versionAuditStatus.
+     */
+    @java.lang.Override
+    public int getVersionAuditStatus() {
+      return versionAuditStatus_;
+    }
+    /**
+     * <pre>
+     * default 2
+     * </pre>
+     *
+     * <code>int32 version_audit_status = 10;</code>
+     * @param value The versionAuditStatus to set.
+     * @return This builder for chaining.
+     */
+    public Builder setVersionAuditStatus(int value) {
+      
+      versionAuditStatus_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * default 2
+     * </pre>
+     *
+     * <code>int32 version_audit_status = 10;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearVersionAuditStatus() {
+      
+      versionAuditStatus_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object recommendTraceId_ = "";
+    /**
+     * <code>string recommend_trace_id = 11;</code>
+     * @return The recommendTraceId.
+     */
+    public java.lang.String getRecommendTraceId() {
+      java.lang.Object ref = recommendTraceId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        recommendTraceId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string recommend_trace_id = 11;</code>
+     * @return The bytes for recommendTraceId.
+     */
+    public com.google.protobuf.ByteString
+        getRecommendTraceIdBytes() {
+      java.lang.Object ref = recommendTraceId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        recommendTraceId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string recommend_trace_id = 11;</code>
+     * @param value The recommendTraceId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRecommendTraceId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      recommendTraceId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string recommend_trace_id = 11;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRecommendTraceId() {
+      
+      recommendTraceId_ = getDefaultInstance().getRecommendTraceId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string recommend_trace_id = 11;</code>
+     * @param value The bytes for recommendTraceId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRecommendTraceIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      recommendTraceId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private long videoId_ ;
+    /**
+     * <code>int64 video_id = 12;</code>
+     * @return The videoId.
+     */
+    @java.lang.Override
+    public long getVideoId() {
+      return videoId_;
+    }
+    /**
+     * <code>int64 video_id = 12;</code>
+     * @param value The videoId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setVideoId(long value) {
+      
+      videoId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 video_id = 12;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearVideoId() {
+      
+      videoId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object city_ = "";
+    /**
+     * <code>string city = 13;</code>
+     * @return The city.
+     */
+    public java.lang.String getCity() {
+      java.lang.Object ref = city_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        city_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string city = 13;</code>
+     * @return The bytes for city.
+     */
+    public com.google.protobuf.ByteString
+        getCityBytes() {
+      java.lang.Object ref = city_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        city_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string city = 13;</code>
+     * @param value The city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCity(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      city_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 13;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCity() {
+      
+      city_ = getDefaultInstance().getCity();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 13;</code>
+     * @param value The bytes for city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      city_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object province_ = "";
+    /**
+     * <code>string province = 14;</code>
+     * @return The province.
+     */
+    public java.lang.String getProvince() {
+      java.lang.Object ref = province_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        province_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string province = 14;</code>
+     * @return The bytes for province.
+     */
+    public com.google.protobuf.ByteString
+        getProvinceBytes() {
+      java.lang.Object ref = province_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        province_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string province = 14;</code>
+     * @param value The province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvince(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      province_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 14;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearProvince() {
+      
+      province_ = getDefaultInstance().getProvince();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 14;</code>
+     * @param value The bytes for province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      province_ = value;
+      onChanged();
+      return this;
+    }
+
+    private MachineInfoProto machineInfo_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+            MachineInfoProto, MachineInfoProto.Builder, MachineInfoProtoOrBuilder> machineInfoBuilder_;
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     * @return Whether the machineInfo field is set.
+     */
+    public boolean hasMachineInfo() {
+      return machineInfoBuilder_ != null || machineInfo_ != null;
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     * @return The machineInfo.
+     */
+    public MachineInfoProto getMachineInfo() {
+      if (machineInfoBuilder_ == null) {
+        return machineInfo_ == null ? MachineInfoProto.getDefaultInstance() : machineInfo_;
+      } else {
+        return machineInfoBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public Builder setMachineInfo(MachineInfoProto value) {
+      if (machineInfoBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        machineInfo_ = value;
+        onChanged();
+      } else {
+        machineInfoBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public Builder setMachineInfo(
+        MachineInfoProto.Builder builderForValue) {
+      if (machineInfoBuilder_ == null) {
+        machineInfo_ = builderForValue.build();
+        onChanged();
+      } else {
+        machineInfoBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public Builder mergeMachineInfo(MachineInfoProto value) {
+      if (machineInfoBuilder_ == null) {
+        if (machineInfo_ != null) {
+          machineInfo_ =
+            MachineInfoProto.newBuilder(machineInfo_).mergeFrom(value).buildPartial();
+        } else {
+          machineInfo_ = value;
+        }
+        onChanged();
+      } else {
+        machineInfoBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public Builder clearMachineInfo() {
+      if (machineInfoBuilder_ == null) {
+        machineInfo_ = null;
+        onChanged();
+      } else {
+        machineInfo_ = null;
+        machineInfoBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public MachineInfoProto.Builder getMachineInfoBuilder() {
+      
+      onChanged();
+      return getMachineInfoFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    public MachineInfoProtoOrBuilder getMachineInfoOrBuilder() {
+      if (machineInfoBuilder_ != null) {
+        return machineInfoBuilder_.getMessageOrBuilder();
+      } else {
+        return machineInfo_ == null ?
+            MachineInfoProto.getDefaultInstance() : machineInfo_;
+      }
+    }
+    /**
+     * <code>.MachineInfoProto machine_info = 15;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+            MachineInfoProto, MachineInfoProto.Builder, MachineInfoProtoOrBuilder>
+        getMachineInfoFieldBuilder() {
+      if (machineInfoBuilder_ == null) {
+        machineInfoBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+                MachineInfoProto, MachineInfoProto.Builder, MachineInfoProtoOrBuilder>(
+                getMachineInfo(),
+                getParentForChildren(),
+                isClean());
+        machineInfo_ = null;
+      }
+      return machineInfoBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:RecommendRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:RecommendRequest)
+  private static final RecommendRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new RecommendRequest();
+  }
+
+  public static RecommendRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RecommendRequest>
+      PARSER = new com.google.protobuf.AbstractParser<RecommendRequest>() {
+    @java.lang.Override
+    public RecommendRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RecommendRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RecommendRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RecommendRequest> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public RecommendRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 215 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendRequestOrBuilder.java

@@ -0,0 +1,215 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface RecommendRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:RecommendRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The requestId.
+   */
+  java.lang.String getRequestId();
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The bytes for requestId.
+   */
+  com.google.protobuf.ByteString
+      getRequestIdBytes();
+
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  java.lang.String getMid();
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  com.google.protobuf.ByteString
+      getMidBytes();
+
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  java.lang.String getUid();
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  com.google.protobuf.ByteString
+      getUidBytes();
+
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 size = 4;</code>
+   * @return The size.
+   */
+  int getSize();
+
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 app_type = 5;</code>
+   * @return The appType.
+   */
+  int getAppType();
+
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The cityCode.
+   */
+  java.lang.String getCityCode();
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The bytes for cityCode.
+   */
+  com.google.protobuf.ByteString
+      getCityCodeBytes();
+
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The provinceCode.
+   */
+  java.lang.String getProvinceCode();
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The bytes for provinceCode.
+   */
+  com.google.protobuf.ByteString
+      getProvinceCodeBytes();
+
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @return A list containing the abExpCode.
+   */
+  java.util.List<java.lang.String>
+      getAbExpCodeList();
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @return The count of abExpCode.
+   */
+  int getAbExpCodeCount();
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @param index The index of the element to return.
+   * @return The abExpCode at the given index.
+   */
+  java.lang.String getAbExpCode(int index);
+  /**
+   * <code>repeated string ab_exp_code = 8;</code>
+   * @param index The index of the value to return.
+   * @return The bytes of the abExpCode at the given index.
+   */
+  com.google.protobuf.ByteString
+      getAbExpCodeBytes(int index);
+
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  int getEventIdCount();
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  boolean containsEventId(
+      java.lang.String key);
+  /**
+   * Use {@link #getEventIdMap()} instead.
+   */
+  @java.lang.Deprecated
+  java.util.Map<java.lang.String, java.lang.String>
+  getEventId();
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+  java.util.Map<java.lang.String, java.lang.String>
+  getEventIdMap();
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+
+  java.lang.String getEventIdOrDefault(
+      java.lang.String key,
+      java.lang.String defaultValue);
+  /**
+   * <code>map&lt;string, string&gt; event_id = 9;</code>
+   */
+
+  java.lang.String getEventIdOrThrow(
+      java.lang.String key);
+
+  /**
+   * <pre>
+   * default 2
+   * </pre>
+   *
+   * <code>int32 version_audit_status = 10;</code>
+   * @return The versionAuditStatus.
+   */
+  int getVersionAuditStatus();
+
+  /**
+   * <code>string recommend_trace_id = 11;</code>
+   * @return The recommendTraceId.
+   */
+  java.lang.String getRecommendTraceId();
+  /**
+   * <code>string recommend_trace_id = 11;</code>
+   * @return The bytes for recommendTraceId.
+   */
+  com.google.protobuf.ByteString
+      getRecommendTraceIdBytes();
+
+  /**
+   * <code>int64 video_id = 12;</code>
+   * @return The videoId.
+   */
+  long getVideoId();
+
+  /**
+   * <code>string city = 13;</code>
+   * @return The city.
+   */
+  java.lang.String getCity();
+  /**
+   * <code>string city = 13;</code>
+   * @return The bytes for city.
+   */
+  com.google.protobuf.ByteString
+      getCityBytes();
+
+  /**
+   * <code>string province = 14;</code>
+   * @return The province.
+   */
+  java.lang.String getProvince();
+  /**
+   * <code>string province = 14;</code>
+   * @return The bytes for province.
+   */
+  com.google.protobuf.ByteString
+      getProvinceBytes();
+
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   * @return Whether the machineInfo field is set.
+   */
+  boolean hasMachineInfo();
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   * @return The machineInfo.
+   */
+  MachineInfoProto getMachineInfo();
+  /**
+   * <code>.MachineInfoProto machine_info = 15;</code>
+   */
+  MachineInfoProtoOrBuilder getMachineInfoOrBuilder();
+}

+ 966 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendResponse.java

@@ -0,0 +1,966 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * <pre>
+ * https://sls.console.aliyun.com/lognext/project/rov-server/logsearch/info
+ * </pre>
+ *
+ * Protobuf type {@code RecommendResponse}
+ */
+public final class RecommendResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:RecommendResponse)
+    RecommendResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RecommendResponse.newBuilder() to construct.
+  private RecommendResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RecommendResponse() {
+    video_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new RecommendResponse();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RecommendResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            com.tzld.piaoquan.recommend.server.gen.common.Result.Builder subBuilder = null;
+            if (result_ != null) {
+              subBuilder = result_.toBuilder();
+            }
+            result_ = input.readMessage(com.tzld.piaoquan.recommend.server.gen.common.Result.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(result_);
+              result_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              video_ = new java.util.ArrayList<VideoProto>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            video_.add(
+                input.readMessage(VideoProto.parser(), extensionRegistry));
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        video_ = java.util.Collections.unmodifiableList(video_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return Recommend.internal_static_RecommendResponse_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return Recommend.internal_static_RecommendResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            RecommendResponse.class, RecommendResponse.Builder.class);
+  }
+
+  public static final int RESULT_FIELD_NUMBER = 1;
+  private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  @java.lang.Override
+  public boolean hasResult() {
+    return result_ != null;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+    return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+    return getResult();
+  }
+
+  public static final int VIDEO_FIELD_NUMBER = 2;
+  private java.util.List<VideoProto> video_;
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<VideoProto> getVideoList() {
+    return video_;
+  }
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<? extends VideoProtoOrBuilder>
+      getVideoOrBuilderList() {
+    return video_;
+  }
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  @java.lang.Override
+  public int getVideoCount() {
+    return video_.size();
+  }
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  @java.lang.Override
+  public VideoProto getVideo(int index) {
+    return video_.get(index);
+  }
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  @java.lang.Override
+  public VideoProtoOrBuilder getVideoOrBuilder(
+      int index) {
+    return video_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (result_ != null) {
+      output.writeMessage(1, getResult());
+    }
+    for (int i = 0; i < video_.size(); i++) {
+      output.writeMessage(2, video_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (result_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getResult());
+    }
+    for (int i = 0; i < video_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, video_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof RecommendResponse)) {
+      return super.equals(obj);
+    }
+    RecommendResponse other = (RecommendResponse) obj;
+
+    if (hasResult() != other.hasResult()) return false;
+    if (hasResult()) {
+      if (!getResult()
+          .equals(other.getResult())) return false;
+    }
+    if (!getVideoList()
+        .equals(other.getVideoList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasResult()) {
+      hash = (37 * hash) + RESULT_FIELD_NUMBER;
+      hash = (53 * hash) + getResult().hashCode();
+    }
+    if (getVideoCount() > 0) {
+      hash = (37 * hash) + VIDEO_FIELD_NUMBER;
+      hash = (53 * hash) + getVideoList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static RecommendResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static RecommendResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static RecommendResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static RecommendResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static RecommendResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static RecommendResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static RecommendResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static RecommendResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(RecommendResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * https://sls.console.aliyun.com/lognext/project/rov-server/logsearch/info
+   * </pre>
+   *
+   * Protobuf type {@code RecommendResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:RecommendResponse)
+          RecommendResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return Recommend.internal_static_RecommendResponse_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return Recommend.internal_static_RecommendResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              RecommendResponse.class, RecommendResponse.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.RecommendResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getVideoFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (resultBuilder_ == null) {
+        result_ = null;
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+      if (videoBuilder_ == null) {
+        video_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        videoBuilder_.clear();
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return Recommend.internal_static_RecommendResponse_descriptor;
+    }
+
+    @java.lang.Override
+    public RecommendResponse getDefaultInstanceForType() {
+      return RecommendResponse.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public RecommendResponse build() {
+      RecommendResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public RecommendResponse buildPartial() {
+      RecommendResponse result = new RecommendResponse(this);
+      int from_bitField0_ = bitField0_;
+      if (resultBuilder_ == null) {
+        result.result_ = result_;
+      } else {
+        result.result_ = resultBuilder_.build();
+      }
+      if (videoBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) != 0)) {
+          video_ = java.util.Collections.unmodifiableList(video_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.video_ = video_;
+      } else {
+        result.video_ = videoBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof RecommendResponse) {
+        return mergeFrom((RecommendResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(RecommendResponse other) {
+      if (other == RecommendResponse.getDefaultInstance()) return this;
+      if (other.hasResult()) {
+        mergeResult(other.getResult());
+      }
+      if (videoBuilder_ == null) {
+        if (!other.video_.isEmpty()) {
+          if (video_.isEmpty()) {
+            video_ = other.video_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureVideoIsMutable();
+            video_.addAll(other.video_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.video_.isEmpty()) {
+          if (videoBuilder_.isEmpty()) {
+            videoBuilder_.dispose();
+            videoBuilder_ = null;
+            video_ = other.video_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            videoBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getVideoFieldBuilder() : null;
+          } else {
+            videoBuilder_.addAllMessages(other.video_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      RecommendResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (RecommendResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> resultBuilder_;
+    /**
+     * <code>.Result result = 1;</code>
+     * @return Whether the result field is set.
+     */
+    public boolean hasResult() {
+      return resultBuilder_ != null || result_ != null;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     * @return The result.
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+      if (resultBuilder_ == null) {
+        return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      } else {
+        return resultBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result_ = value;
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(
+        com.tzld.piaoquan.recommend.server.gen.common.Result.Builder builderForValue) {
+      if (resultBuilder_ == null) {
+        result_ = builderForValue.build();
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder mergeResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (result_ != null) {
+          result_ =
+            com.tzld.piaoquan.recommend.server.gen.common.Result.newBuilder(result_).mergeFrom(value).buildPartial();
+        } else {
+          result_ = value;
+        }
+        onChanged();
+      } else {
+        resultBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder clearResult() {
+      if (resultBuilder_ == null) {
+        result_ = null;
+        onChanged();
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result.Builder getResultBuilder() {
+      
+      onChanged();
+      return getResultFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+      if (resultBuilder_ != null) {
+        return resultBuilder_.getMessageOrBuilder();
+      } else {
+        return result_ == null ?
+            com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> 
+        getResultFieldBuilder() {
+      if (resultBuilder_ == null) {
+        resultBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder>(
+                getResult(),
+                getParentForChildren(),
+                isClean());
+        result_ = null;
+      }
+      return resultBuilder_;
+    }
+
+    private java.util.List<VideoProto> video_ =
+      java.util.Collections.emptyList();
+    private void ensureVideoIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        video_ = new java.util.ArrayList<VideoProto>(video_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            VideoProto, VideoProto.Builder, VideoProtoOrBuilder> videoBuilder_;
+
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public java.util.List<VideoProto> getVideoList() {
+      if (videoBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(video_);
+      } else {
+        return videoBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public int getVideoCount() {
+      if (videoBuilder_ == null) {
+        return video_.size();
+      } else {
+        return videoBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public VideoProto getVideo(int index) {
+      if (videoBuilder_ == null) {
+        return video_.get(index);
+      } else {
+        return videoBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder setVideo(
+        int index, VideoProto value) {
+      if (videoBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureVideoIsMutable();
+        video_.set(index, value);
+        onChanged();
+      } else {
+        videoBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder setVideo(
+        int index, VideoProto.Builder builderForValue) {
+      if (videoBuilder_ == null) {
+        ensureVideoIsMutable();
+        video_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        videoBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder addVideo(VideoProto value) {
+      if (videoBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureVideoIsMutable();
+        video_.add(value);
+        onChanged();
+      } else {
+        videoBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder addVideo(
+        int index, VideoProto value) {
+      if (videoBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureVideoIsMutable();
+        video_.add(index, value);
+        onChanged();
+      } else {
+        videoBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder addVideo(
+        VideoProto.Builder builderForValue) {
+      if (videoBuilder_ == null) {
+        ensureVideoIsMutable();
+        video_.add(builderForValue.build());
+        onChanged();
+      } else {
+        videoBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder addVideo(
+        int index, VideoProto.Builder builderForValue) {
+      if (videoBuilder_ == null) {
+        ensureVideoIsMutable();
+        video_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        videoBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder addAllVideo(
+        java.lang.Iterable<? extends VideoProto> values) {
+      if (videoBuilder_ == null) {
+        ensureVideoIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, video_);
+        onChanged();
+      } else {
+        videoBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder clearVideo() {
+      if (videoBuilder_ == null) {
+        video_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        videoBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public Builder removeVideo(int index) {
+      if (videoBuilder_ == null) {
+        ensureVideoIsMutable();
+        video_.remove(index);
+        onChanged();
+      } else {
+        videoBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public VideoProto.Builder getVideoBuilder(
+        int index) {
+      return getVideoFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public VideoProtoOrBuilder getVideoOrBuilder(
+        int index) {
+      if (videoBuilder_ == null) {
+        return video_.get(index);  } else {
+        return videoBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public java.util.List<? extends VideoProtoOrBuilder>
+         getVideoOrBuilderList() {
+      if (videoBuilder_ != null) {
+        return videoBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(video_);
+      }
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public VideoProto.Builder addVideoBuilder() {
+      return getVideoFieldBuilder().addBuilder(
+          VideoProto.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public VideoProto.Builder addVideoBuilder(
+        int index) {
+      return getVideoFieldBuilder().addBuilder(
+          index, VideoProto.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .VideoProto video = 2;</code>
+     */
+    public java.util.List<VideoProto.Builder>
+         getVideoBuilderList() {
+      return getVideoFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+            VideoProto, VideoProto.Builder, VideoProtoOrBuilder>
+        getVideoFieldBuilder() {
+      if (videoBuilder_ == null) {
+        videoBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+                VideoProto, VideoProto.Builder, VideoProtoOrBuilder>(
+                video_,
+                ((bitField0_ & 0x00000001) != 0),
+                getParentForChildren(),
+                isClean());
+        video_ = null;
+      }
+      return videoBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:RecommendResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:RecommendResponse)
+  private static final RecommendResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new RecommendResponse();
+  }
+
+  public static RecommendResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RecommendResponse>
+      PARSER = new com.google.protobuf.AbstractParser<RecommendResponse>() {
+    @java.lang.Override
+    public RecommendResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RecommendResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RecommendResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RecommendResponse> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public RecommendResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 48 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendResponseOrBuilder.java

@@ -0,0 +1,48 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface RecommendResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:RecommendResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  boolean hasResult();
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.Result getResult();
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder();
+
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  java.util.List<VideoProto>
+      getVideoList();
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  VideoProto getVideo(int index);
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  int getVideoCount();
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  java.util.List<? extends VideoProtoOrBuilder>
+      getVideoOrBuilderList();
+  /**
+   * <code>repeated .VideoProto video = 2;</code>
+   */
+  VideoProtoOrBuilder getVideoOrBuilder(
+      int index);
+}

+ 316 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendService.java

@@ -0,0 +1,316 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * Protobuf service {@code RecommendService}
+ */
+public  abstract class RecommendService
+    implements com.google.protobuf.Service {
+  protected RecommendService() {}
+
+  public interface Interface {
+    /**
+     * <pre>
+     * 首页推荐和tab分类 /applet/video/homepage/recommend
+     * </pre>
+     *
+     * <code>rpc HomepageRecommend(.RecommendRequest) returns (.RecommendResponse);</code>
+     */
+    public abstract void homepageRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request,
+        com.google.protobuf.RpcCallback<RecommendResponse> done);
+
+    /**
+     * <code>rpc RelevantRecommend(.RecommendRequest) returns (.RecommendResponse);</code>
+     */
+    public abstract void relevantRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request,
+        com.google.protobuf.RpcCallback<RecommendResponse> done);
+
+  }
+
+  public static com.google.protobuf.Service newReflectiveService(
+      final Interface impl) {
+    return new RecommendService() {
+      @java.lang.Override
+      public  void homepageRecommend(
+          com.google.protobuf.RpcController controller,
+          RecommendRequest request,
+          com.google.protobuf.RpcCallback<RecommendResponse> done) {
+        impl.homepageRecommend(controller, request, done);
+      }
+
+      @java.lang.Override
+      public  void relevantRecommend(
+          com.google.protobuf.RpcController controller,
+          RecommendRequest request,
+          com.google.protobuf.RpcCallback<RecommendResponse> done) {
+        impl.relevantRecommend(controller, request, done);
+      }
+
+    };
+  }
+
+  public static com.google.protobuf.BlockingService
+      newReflectiveBlockingService(final BlockingInterface impl) {
+    return new com.google.protobuf.BlockingService() {
+      public final com.google.protobuf.Descriptors.ServiceDescriptor
+          getDescriptorForType() {
+        return getDescriptor();
+      }
+
+      public final com.google.protobuf.Message callBlockingMethod(
+          com.google.protobuf.Descriptors.MethodDescriptor method,
+          com.google.protobuf.RpcController controller,
+          com.google.protobuf.Message request)
+          throws com.google.protobuf.ServiceException {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.callBlockingMethod() given method descriptor for " +
+            "wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return impl.homepageRecommend(controller, (RecommendRequest)request);
+          case 1:
+            return impl.relevantRecommend(controller, (RecommendRequest)request);
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+      public final com.google.protobuf.Message
+          getRequestPrototype(
+          com.google.protobuf.Descriptors.MethodDescriptor method) {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.getRequestPrototype() given method " +
+            "descriptor for wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return RecommendRequest.getDefaultInstance();
+          case 1:
+            return RecommendRequest.getDefaultInstance();
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+      public final com.google.protobuf.Message
+          getResponsePrototype(
+          com.google.protobuf.Descriptors.MethodDescriptor method) {
+        if (method.getService() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "Service.getResponsePrototype() given method " +
+            "descriptor for wrong service type.");
+        }
+        switch(method.getIndex()) {
+          case 0:
+            return RecommendResponse.getDefaultInstance();
+          case 1:
+            return RecommendResponse.getDefaultInstance();
+          default:
+            throw new java.lang.AssertionError("Can't get here.");
+        }
+      }
+
+    };
+  }
+
+  /**
+   * <pre>
+   * 首页推荐和tab分类 /applet/video/homepage/recommend
+   * </pre>
+   *
+   * <code>rpc HomepageRecommend(.RecommendRequest) returns (.RecommendResponse);</code>
+   */
+  public abstract void homepageRecommend(
+      com.google.protobuf.RpcController controller,
+      RecommendRequest request,
+      com.google.protobuf.RpcCallback<RecommendResponse> done);
+
+  /**
+   * <code>rpc RelevantRecommend(.RecommendRequest) returns (.RecommendResponse);</code>
+   */
+  public abstract void relevantRecommend(
+      com.google.protobuf.RpcController controller,
+      RecommendRequest request,
+      com.google.protobuf.RpcCallback<RecommendResponse> done);
+
+  public static final
+      com.google.protobuf.Descriptors.ServiceDescriptor
+      getDescriptor() {
+    return Recommend.getDescriptor().getServices().get(0);
+  }
+  public final com.google.protobuf.Descriptors.ServiceDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+
+  public final void callMethod(
+      com.google.protobuf.Descriptors.MethodDescriptor method,
+      com.google.protobuf.RpcController controller,
+      com.google.protobuf.Message request,
+      com.google.protobuf.RpcCallback<
+        com.google.protobuf.Message> done) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.callMethod() given method descriptor for wrong " +
+        "service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        this.homepageRecommend(controller, (RecommendRequest)request,
+          com.google.protobuf.RpcUtil.<RecommendResponse>specializeCallback(
+            done));
+        return;
+      case 1:
+        this.relevantRecommend(controller, (RecommendRequest)request,
+          com.google.protobuf.RpcUtil.<RecommendResponse>specializeCallback(
+            done));
+        return;
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public final com.google.protobuf.Message
+      getRequestPrototype(
+      com.google.protobuf.Descriptors.MethodDescriptor method) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.getRequestPrototype() given method " +
+        "descriptor for wrong service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        return RecommendRequest.getDefaultInstance();
+      case 1:
+        return RecommendRequest.getDefaultInstance();
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public final com.google.protobuf.Message
+      getResponsePrototype(
+      com.google.protobuf.Descriptors.MethodDescriptor method) {
+    if (method.getService() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "Service.getResponsePrototype() given method " +
+        "descriptor for wrong service type.");
+    }
+    switch(method.getIndex()) {
+      case 0:
+        return RecommendResponse.getDefaultInstance();
+      case 1:
+        return RecommendResponse.getDefaultInstance();
+      default:
+        throw new java.lang.AssertionError("Can't get here.");
+    }
+  }
+
+  public static Stub newStub(
+      com.google.protobuf.RpcChannel channel) {
+    return new Stub(channel);
+  }
+
+  public static final class Stub extends RecommendService implements Interface {
+    private Stub(com.google.protobuf.RpcChannel channel) {
+      this.channel = channel;
+    }
+
+    private final com.google.protobuf.RpcChannel channel;
+
+    public com.google.protobuf.RpcChannel getChannel() {
+      return channel;
+    }
+
+    public  void homepageRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request,
+        com.google.protobuf.RpcCallback<RecommendResponse> done) {
+      channel.callMethod(
+        getDescriptor().getMethods().get(0),
+        controller,
+        request,
+        RecommendResponse.getDefaultInstance(),
+        com.google.protobuf.RpcUtil.generalizeCallback(
+          done,
+          RecommendResponse.class,
+          RecommendResponse.getDefaultInstance()));
+    }
+
+    public  void relevantRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request,
+        com.google.protobuf.RpcCallback<RecommendResponse> done) {
+      channel.callMethod(
+        getDescriptor().getMethods().get(1),
+        controller,
+        request,
+        RecommendResponse.getDefaultInstance(),
+        com.google.protobuf.RpcUtil.generalizeCallback(
+          done,
+          RecommendResponse.class,
+          RecommendResponse.getDefaultInstance()));
+    }
+  }
+
+  public static BlockingInterface newBlockingStub(
+      com.google.protobuf.BlockingRpcChannel channel) {
+    return new BlockingStub(channel);
+  }
+
+  public interface BlockingInterface {
+    public RecommendResponse homepageRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request)
+        throws com.google.protobuf.ServiceException;
+
+    public RecommendResponse relevantRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request)
+        throws com.google.protobuf.ServiceException;
+  }
+
+  private static final class BlockingStub implements BlockingInterface {
+    private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {
+      this.channel = channel;
+    }
+
+    private final com.google.protobuf.BlockingRpcChannel channel;
+
+    public RecommendResponse homepageRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request)
+        throws com.google.protobuf.ServiceException {
+      return (RecommendResponse) channel.callBlockingMethod(
+        getDescriptor().getMethods().get(0),
+        controller,
+        request,
+        RecommendResponse.getDefaultInstance());
+    }
+
+
+    public RecommendResponse relevantRecommend(
+        com.google.protobuf.RpcController controller,
+        RecommendRequest request)
+        throws com.google.protobuf.ServiceException {
+      return (RecommendResponse) channel.callBlockingMethod(
+        getDescriptor().getMethods().get(1),
+        controller,
+        request,
+        RecommendResponse.getDefaultInstance());
+    }
+
+  }
+
+  // @@protoc_insertion_point(class_scope:RecommendService)
+}
+

+ 367 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/RecommendServiceGrpc.java

@@ -0,0 +1,367 @@
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.34.1)",
+    comments = "Source: com/tzld/piaoquan/recommend/server/recommend.proto")
+public final class RecommendServiceGrpc {
+
+  private RecommendServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "RecommendService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<RecommendRequest,
+          RecommendResponse> getHomepageRecommendMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "HomepageRecommend",
+      requestType = RecommendRequest.class,
+      responseType = RecommendResponse.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<RecommendRequest,
+          RecommendResponse> getHomepageRecommendMethod() {
+    io.grpc.MethodDescriptor<RecommendRequest, RecommendResponse> getHomepageRecommendMethod;
+    if ((getHomepageRecommendMethod = RecommendServiceGrpc.getHomepageRecommendMethod) == null) {
+      synchronized (RecommendServiceGrpc.class) {
+        if ((getHomepageRecommendMethod = RecommendServiceGrpc.getHomepageRecommendMethod) == null) {
+          RecommendServiceGrpc.getHomepageRecommendMethod = getHomepageRecommendMethod =
+              io.grpc.MethodDescriptor.<RecommendRequest, RecommendResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "HomepageRecommend"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  RecommendRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  RecommendResponse.getDefaultInstance()))
+              .setSchemaDescriptor(new RecommendServiceMethodDescriptorSupplier("HomepageRecommend"))
+              .build();
+        }
+      }
+    }
+    return getHomepageRecommendMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<RecommendRequest,
+          RecommendResponse> getRelevantRecommendMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "RelevantRecommend",
+      requestType = RecommendRequest.class,
+      responseType = RecommendResponse.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<RecommendRequest,
+          RecommendResponse> getRelevantRecommendMethod() {
+    io.grpc.MethodDescriptor<RecommendRequest, RecommendResponse> getRelevantRecommendMethod;
+    if ((getRelevantRecommendMethod = RecommendServiceGrpc.getRelevantRecommendMethod) == null) {
+      synchronized (RecommendServiceGrpc.class) {
+        if ((getRelevantRecommendMethod = RecommendServiceGrpc.getRelevantRecommendMethod) == null) {
+          RecommendServiceGrpc.getRelevantRecommendMethod = getRelevantRecommendMethod =
+              io.grpc.MethodDescriptor.<RecommendRequest, RecommendResponse>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "RelevantRecommend"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  RecommendRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  RecommendResponse.getDefaultInstance()))
+              .setSchemaDescriptor(new RecommendServiceMethodDescriptorSupplier("RelevantRecommend"))
+              .build();
+        }
+      }
+    }
+    return getRelevantRecommendMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static RecommendServiceStub newStub(io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<RecommendServiceStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<RecommendServiceStub>() {
+        @java.lang.Override
+        public RecommendServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new RecommendServiceStub(channel, callOptions);
+        }
+      };
+    return RecommendServiceStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static RecommendServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<RecommendServiceBlockingStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<RecommendServiceBlockingStub>() {
+        @java.lang.Override
+        public RecommendServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new RecommendServiceBlockingStub(channel, callOptions);
+        }
+      };
+    return RecommendServiceBlockingStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static RecommendServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<RecommendServiceFutureStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<RecommendServiceFutureStub>() {
+        @java.lang.Override
+        public RecommendServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new RecommendServiceFutureStub(channel, callOptions);
+        }
+      };
+    return RecommendServiceFutureStub.newStub(factory, channel);
+  }
+
+  /**
+   */
+  public static abstract class RecommendServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     * <pre>
+     * 首页推荐和tab分类 /applet/video/homepage/recommend
+     * </pre>
+     */
+    public void homepageRecommend(RecommendRequest request,
+                                  io.grpc.stub.StreamObserver<RecommendResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getHomepageRecommendMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void relevantRecommend(RecommendRequest request,
+                                  io.grpc.stub.StreamObserver<RecommendResponse> responseObserver) {
+      asyncUnimplementedUnaryCall(getRelevantRecommendMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getHomepageRecommendMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                      RecommendRequest,
+                      RecommendResponse>(
+                  this, METHODID_HOMEPAGE_RECOMMEND)))
+          .addMethod(
+            getRelevantRecommendMethod(),
+            asyncUnaryCall(
+              new MethodHandlers<
+                      RecommendRequest,
+                      RecommendResponse>(
+                  this, METHODID_RELEVANT_RECOMMEND)))
+          .build();
+    }
+  }
+
+  /**
+   */
+  public static final class RecommendServiceStub extends io.grpc.stub.AbstractAsyncStub<RecommendServiceStub> {
+    private RecommendServiceStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected RecommendServiceStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new RecommendServiceStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * 首页推荐和tab分类 /applet/video/homepage/recommend
+     * </pre>
+     */
+    public void homepageRecommend(RecommendRequest request,
+                                  io.grpc.stub.StreamObserver<RecommendResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getHomepageRecommendMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void relevantRecommend(RecommendRequest request,
+                                  io.grpc.stub.StreamObserver<RecommendResponse> responseObserver) {
+      asyncUnaryCall(
+          getChannel().newCall(getRelevantRecommendMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   */
+  public static final class RecommendServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub<RecommendServiceBlockingStub> {
+    private RecommendServiceBlockingStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected RecommendServiceBlockingStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new RecommendServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * 首页推荐和tab分类 /applet/video/homepage/recommend
+     * </pre>
+     */
+    public RecommendResponse homepageRecommend(RecommendRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getHomepageRecommendMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public RecommendResponse relevantRecommend(RecommendRequest request) {
+      return blockingUnaryCall(
+          getChannel(), getRelevantRecommendMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   */
+  public static final class RecommendServiceFutureStub extends io.grpc.stub.AbstractFutureStub<RecommendServiceFutureStub> {
+    private RecommendServiceFutureStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected RecommendServiceFutureStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new RecommendServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     * <pre>
+     * 首页推荐和tab分类 /applet/video/homepage/recommend
+     * </pre>
+     */
+    public com.google.common.util.concurrent.ListenableFuture<RecommendResponse> homepageRecommend(
+        RecommendRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getHomepageRecommendMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<RecommendResponse> relevantRecommend(
+        RecommendRequest request) {
+      return futureUnaryCall(
+          getChannel().newCall(getRelevantRecommendMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_HOMEPAGE_RECOMMEND = 0;
+  private static final int METHODID_RELEVANT_RECOMMEND = 1;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final RecommendServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(RecommendServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_HOMEPAGE_RECOMMEND:
+          serviceImpl.homepageRecommend((RecommendRequest) request,
+              (io.grpc.stub.StreamObserver<RecommendResponse>) responseObserver);
+          break;
+        case METHODID_RELEVANT_RECOMMEND:
+          serviceImpl.relevantRecommend((RecommendRequest) request,
+              (io.grpc.stub.StreamObserver<RecommendResponse>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class RecommendServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    RecommendServiceBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return Recommend.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("RecommendService");
+    }
+  }
+
+  private static final class RecommendServiceFileDescriptorSupplier
+      extends RecommendServiceBaseDescriptorSupplier {
+    RecommendServiceFileDescriptorSupplier() {}
+  }
+
+  private static final class RecommendServiceMethodDescriptorSupplier
+      extends RecommendServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    RecommendServiceMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (RecommendServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new RecommendServiceFileDescriptorSupplier())
+              .addMethod(getHomepageRecommendMethod())
+              .addMethod(getRelevantRecommendMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}

+ 1232 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/VideoProto.java

@@ -0,0 +1,1232 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+/**
+ * <pre>
+ * RecommendRovVideoDTO
+ * </pre>
+ *
+ * Protobuf type {@code VideoProto}
+ */
+public final class VideoProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:VideoProto)
+    VideoProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use VideoProto.newBuilder() to construct.
+  private VideoProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private VideoProto() {
+    pushFrom_ = "";
+    abCode_ = "";
+    flowPool_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new VideoProto();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private VideoProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            videoId_ = input.readInt64();
+            break;
+          }
+          case 17: {
+
+            rovScore_ = input.readDouble();
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            pushFrom_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            abCode_ = s;
+            break;
+          }
+          case 41: {
+
+            sortScore_ = input.readDouble();
+            break;
+          }
+          case 48: {
+
+            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)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return Recommend.internal_static_VideoProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return Recommend.internal_static_VideoProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            VideoProto.class, VideoProto.Builder.class);
+  }
+
+  public static final int VIDEO_ID_FIELD_NUMBER = 1;
+  private long videoId_;
+  /**
+   * <code>int64 video_id = 1;</code>
+   * @return The videoId.
+   */
+  @java.lang.Override
+  public long getVideoId() {
+    return videoId_;
+  }
+
+  public static final int ROV_SCORE_FIELD_NUMBER = 2;
+  private double rovScore_;
+  /**
+   * <code>double rov_score = 2;</code>
+   * @return The rovScore.
+   */
+  @java.lang.Override
+  public double getRovScore() {
+    return rovScore_;
+  }
+
+  public static final int PUSH_FROM_FIELD_NUMBER = 3;
+  private volatile java.lang.Object pushFrom_;
+  /**
+   * <code>string push_from = 3;</code>
+   * @return The pushFrom.
+   */
+  @java.lang.Override
+  public java.lang.String getPushFrom() {
+    java.lang.Object ref = pushFrom_;
+    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();
+      pushFrom_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string push_from = 3;</code>
+   * @return The bytes for pushFrom.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getPushFromBytes() {
+    java.lang.Object ref = pushFrom_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      pushFrom_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int AB_CODE_FIELD_NUMBER = 4;
+  private volatile java.lang.Object abCode_;
+  /**
+   * <code>string ab_code = 4;</code>
+   * @return The abCode.
+   */
+  @java.lang.Override
+  public java.lang.String getAbCode() {
+    java.lang.Object ref = abCode_;
+    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();
+      abCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string ab_code = 4;</code>
+   * @return The bytes for abCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getAbCodeBytes() {
+    java.lang.Object ref = abCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      abCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int SORT_SCORE_FIELD_NUMBER = 5;
+  private double sortScore_;
+  /**
+   * <code>double sort_score = 5;</code>
+   * @return The sortScore.
+   */
+  @java.lang.Override
+  public double getSortScore() {
+    return sortScore_;
+  }
+
+  public static final int POSITION_FIELD_NUMBER = 6;
+  private int position_;
+  /**
+   * <code>int32 position = 6;</code>
+   * @return The position.
+   */
+  @java.lang.Override
+  public int getPosition() {
+    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() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (videoId_ != 0L) {
+      output.writeInt64(1, videoId_);
+    }
+    if (rovScore_ != 0D) {
+      output.writeDouble(2, rovScore_);
+    }
+    if (!getPushFromBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, pushFrom_);
+    }
+    if (!getAbCodeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, abCode_);
+    }
+    if (sortScore_ != 0D) {
+      output.writeDouble(5, sortScore_);
+    }
+    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);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (videoId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(1, videoId_);
+    }
+    if (rovScore_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(2, rovScore_);
+    }
+    if (!getPushFromBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, pushFrom_);
+    }
+    if (!getAbCodeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, abCode_);
+    }
+    if (sortScore_ != 0D) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeDoubleSize(5, sortScore_);
+    }
+    if (position_ != 0) {
+      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;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof VideoProto)) {
+      return super.equals(obj);
+    }
+    VideoProto other = (VideoProto) obj;
+
+    if (getVideoId()
+        != other.getVideoId()) return false;
+    if (java.lang.Double.doubleToLongBits(getRovScore())
+        != java.lang.Double.doubleToLongBits(
+            other.getRovScore())) return false;
+    if (!getPushFrom()
+        .equals(other.getPushFrom())) return false;
+    if (!getAbCode()
+        .equals(other.getAbCode())) return false;
+    if (java.lang.Double.doubleToLongBits(getSortScore())
+        != java.lang.Double.doubleToLongBits(
+            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;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + VIDEO_ID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getVideoId());
+    hash = (37 * hash) + ROV_SCORE_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        java.lang.Double.doubleToLongBits(getRovScore()));
+    hash = (37 * hash) + PUSH_FROM_FIELD_NUMBER;
+    hash = (53 * hash) + getPushFrom().hashCode();
+    hash = (37 * hash) + AB_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getAbCode().hashCode();
+    hash = (37 * hash) + SORT_SCORE_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        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;
+  }
+
+  public static VideoProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static VideoProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static VideoProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static VideoProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static VideoProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static VideoProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static VideoProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static VideoProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static VideoProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static VideoProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static VideoProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static VideoProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(VideoProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * RecommendRovVideoDTO
+   * </pre>
+   *
+   * Protobuf type {@code VideoProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:VideoProto)
+          VideoProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return Recommend.internal_static_VideoProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return Recommend.internal_static_VideoProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              VideoProto.class, VideoProto.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.recommend.VideoProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      videoId_ = 0L;
+
+      rovScore_ = 0D;
+
+      pushFrom_ = "";
+
+      abCode_ = "";
+
+      sortScore_ = 0D;
+
+      position_ = 0;
+
+      flowPool_ = "";
+
+      isInFlowPool_ = 0;
+
+      rand_ = 0D;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return Recommend.internal_static_VideoProto_descriptor;
+    }
+
+    @java.lang.Override
+    public VideoProto getDefaultInstanceForType() {
+      return VideoProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public VideoProto build() {
+      VideoProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public VideoProto buildPartial() {
+      VideoProto result = new VideoProto(this);
+      result.videoId_ = videoId_;
+      result.rovScore_ = rovScore_;
+      result.pushFrom_ = pushFrom_;
+      result.abCode_ = abCode_;
+      result.sortScore_ = sortScore_;
+      result.position_ = position_;
+      result.flowPool_ = flowPool_;
+      result.isInFlowPool_ = isInFlowPool_;
+      result.rand_ = rand_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof VideoProto) {
+        return mergeFrom((VideoProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(VideoProto other) {
+      if (other == VideoProto.getDefaultInstance()) return this;
+      if (other.getVideoId() != 0L) {
+        setVideoId(other.getVideoId());
+      }
+      if (other.getRovScore() != 0D) {
+        setRovScore(other.getRovScore());
+      }
+      if (!other.getPushFrom().isEmpty()) {
+        pushFrom_ = other.pushFrom_;
+        onChanged();
+      }
+      if (!other.getAbCode().isEmpty()) {
+        abCode_ = other.abCode_;
+        onChanged();
+      }
+      if (other.getSortScore() != 0D) {
+        setSortScore(other.getSortScore());
+      }
+      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;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      VideoProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (VideoProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private long videoId_ ;
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @return The videoId.
+     */
+    @java.lang.Override
+    public long getVideoId() {
+      return videoId_;
+    }
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @param value The videoId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setVideoId(long value) {
+      
+      videoId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 video_id = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearVideoId() {
+      
+      videoId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private double rovScore_ ;
+    /**
+     * <code>double rov_score = 2;</code>
+     * @return The rovScore.
+     */
+    @java.lang.Override
+    public double getRovScore() {
+      return rovScore_;
+    }
+    /**
+     * <code>double rov_score = 2;</code>
+     * @param value The rovScore to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRovScore(double value) {
+      
+      rovScore_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double rov_score = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRovScore() {
+      
+      rovScore_ = 0D;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object pushFrom_ = "";
+    /**
+     * <code>string push_from = 3;</code>
+     * @return The pushFrom.
+     */
+    public java.lang.String getPushFrom() {
+      java.lang.Object ref = pushFrom_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        pushFrom_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string push_from = 3;</code>
+     * @return The bytes for pushFrom.
+     */
+    public com.google.protobuf.ByteString
+        getPushFromBytes() {
+      java.lang.Object ref = pushFrom_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        pushFrom_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string push_from = 3;</code>
+     * @param value The pushFrom to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPushFrom(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      pushFrom_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string push_from = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearPushFrom() {
+      
+      pushFrom_ = getDefaultInstance().getPushFrom();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string push_from = 3;</code>
+     * @param value The bytes for pushFrom to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPushFromBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      pushFrom_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object abCode_ = "";
+    /**
+     * <code>string ab_code = 4;</code>
+     * @return The abCode.
+     */
+    public java.lang.String getAbCode() {
+      java.lang.Object ref = abCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        abCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string ab_code = 4;</code>
+     * @return The bytes for abCode.
+     */
+    public com.google.protobuf.ByteString
+        getAbCodeBytes() {
+      java.lang.Object ref = abCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        abCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string ab_code = 4;</code>
+     * @param value The abCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAbCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      abCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string ab_code = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearAbCode() {
+      
+      abCode_ = getDefaultInstance().getAbCode();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string ab_code = 4;</code>
+     * @param value The bytes for abCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAbCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      abCode_ = value;
+      onChanged();
+      return this;
+    }
+
+    private double sortScore_ ;
+    /**
+     * <code>double sort_score = 5;</code>
+     * @return The sortScore.
+     */
+    @java.lang.Override
+    public double getSortScore() {
+      return sortScore_;
+    }
+    /**
+     * <code>double sort_score = 5;</code>
+     * @param value The sortScore to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSortScore(double value) {
+      
+      sortScore_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>double sort_score = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearSortScore() {
+      
+      sortScore_ = 0D;
+      onChanged();
+      return this;
+    }
+
+    private int position_ ;
+    /**
+     * <code>int32 position = 6;</code>
+     * @return The position.
+     */
+    @java.lang.Override
+    public int getPosition() {
+      return position_;
+    }
+    /**
+     * <code>int32 position = 6;</code>
+     * @param value The position to set.
+     * @return This builder for chaining.
+     */
+    public Builder setPosition(int value) {
+      
+      position_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 position = 6;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearPosition() {
+      
+      position_ = 0;
+      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) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:VideoProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:VideoProto)
+  private static final VideoProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new VideoProto();
+  }
+
+  public static VideoProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<VideoProto>
+      PARSER = new com.google.protobuf.AbstractParser<VideoProto>() {
+    @java.lang.Override
+    public VideoProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new VideoProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<VideoProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<VideoProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public VideoProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 81 - 0
recommend-feature-client/src/main/java/com/tzld/piaoquan/recommend/feature/gen/recommend/VideoProtoOrBuilder.java

@@ -0,0 +1,81 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/recommend.proto
+
+package com.tzld.piaoquan.recommend.feature.gen.recommend;
+
+public interface VideoProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:VideoProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>int64 video_id = 1;</code>
+   * @return The videoId.
+   */
+  long getVideoId();
+
+  /**
+   * <code>double rov_score = 2;</code>
+   * @return The rovScore.
+   */
+  double getRovScore();
+
+  /**
+   * <code>string push_from = 3;</code>
+   * @return The pushFrom.
+   */
+  java.lang.String getPushFrom();
+  /**
+   * <code>string push_from = 3;</code>
+   * @return The bytes for pushFrom.
+   */
+  com.google.protobuf.ByteString
+      getPushFromBytes();
+
+  /**
+   * <code>string ab_code = 4;</code>
+   * @return The abCode.
+   */
+  java.lang.String getAbCode();
+  /**
+   * <code>string ab_code = 4;</code>
+   * @return The bytes for abCode.
+   */
+  com.google.protobuf.ByteString
+      getAbCodeBytes();
+
+  /**
+   * <code>double sort_score = 5;</code>
+   * @return The sortScore.
+   */
+  double getSortScore();
+
+  /**
+   * <code>int32 position = 6;</code>
+   * @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();
+}

+ 49 - 0
recommend-feature-client/src/main/proto/ctr_samples.proto

@@ -0,0 +1,49 @@
+syntax = "proto3";
+
+
+option java_multiple_files = true;
+option java_package = "com.tzld.piaoquan.recommend.server.gen.recommend";
+option java_generic_services = true;
+
+
+
+message FeatureGroup {
+    string type = 1;
+    int32 id = 2;
+    string name = 3;
+    string field = 4;
+}
+
+message BaseFeature {
+    int64 id = 1;
+    int64 identifier = 2;
+    string fea = 3;
+    double value = 4;
+    double weight =5;
+}
+
+
+message GroupedFeature {
+    FeatureGroup group = 1;
+    int32 count = 2;
+    repeated BaseFeature features = 3;
+}
+
+
+
+message LRWeight {
+    int32 group_num = 1;
+    repeated BaseFeature features = 2;
+}
+
+
+
+message LRSamples {
+    int32 is_click = 1;
+    int32 group_num = 2;
+    int32 count = 3;
+    repeated GroupedFeature features = 4;
+    double weight = 5;
+    double predict_ctr = 6;
+}
+