|
37 | 37 | import feast.serving.ServingAPIProto.GetOnlineFeaturesResponse.FeatureDataSet; |
38 | 38 | import feast.serving.exception.FeatureRetrievalException; |
39 | 39 | import feast.storage.RedisProto.RedisKey; |
40 | | -import feast.types.FeatureProto.Field; |
| 40 | +import feast.types.FieldProto.Field; |
41 | 41 | import feast.types.FeatureRowProto.FeatureRow; |
42 | 42 | import feast.types.FeatureRowProto.FeatureRow.Builder; |
43 | 43 | import feast.types.ValueProto.Value; |
44 | 44 | import io.opentracing.Scope; |
45 | 45 | import io.opentracing.Tracer; |
46 | 46 | import java.util.ArrayList; |
| 47 | +import java.util.HashMap; |
47 | 48 | import java.util.List; |
| 49 | +import java.util.Map; |
48 | 50 | import java.util.stream.Collectors; |
49 | 51 | import lombok.extern.slf4j.Slf4j; |
50 | 52 | import redis.clients.jedis.Jedis; |
@@ -113,11 +115,10 @@ public GetOnlineFeaturesResponse getOnlineFeatures(GetFeaturesRequest request) { |
113 | 115 | private List<RedisKey> getRedisKeys(List<String> entityNames, |
114 | 116 | List<EntityDataSetRow> entityDataSetRows, FeatureSet featureSet) { |
115 | 117 | try (Scope scope = tracer.buildSpan("Redis-makeRedisKeys").startActive(true)) { |
116 | | - List<RedisKey> redisKeys = new ArrayList<>(); |
117 | 118 | String featureSetId = String.format("%s:%s", featureSet.getName(), featureSet.getVersion()); |
118 | | - for (EntityDataSetRow entityDataSetRow : entityDataSetRows) { |
119 | | - redisKeys.add(makeRedisKey(featureSetId, entityNames, entityDataSetRow)); |
120 | | - } |
| 119 | + List<RedisKey> redisKeys = entityDataSetRows.parallelStream() |
| 120 | + .map(row -> makeRedisKey(featureSetId, entityNames, row)) |
| 121 | + .collect(Collectors.toList()); |
121 | 122 | return redisKeys; |
122 | 123 | } |
123 | 124 | } |
@@ -167,36 +168,51 @@ private List<FeatureRow> sendAndProcessMultiGet(List<RedisKey> redisKeys, |
167 | 168 | List<String> requestedColumns, FeatureSet featureSet) throws InvalidProtocolBufferException { |
168 | 169 | List<byte[]> jedisResps = sendMultiGet(redisKeys); |
169 | 170 |
|
170 | | - List<FeatureRow> featureRows = new ArrayList<>(); |
171 | | - |
172 | 171 | try (Scope scope = tracer.buildSpan("Redis-processResponse").startActive(true)) { |
| 172 | + List<FeatureRow> featureRows = new ArrayList<>(); |
| 173 | + String featureSetName = String.format("%s:%s", featureSet.getName(), featureSet.getVersion()); |
173 | 174 | for (int i = 0; i < jedisResps.size(); i++) { |
174 | | - byte[] jedisResp = jedisResps.get(i); |
175 | | - if (jedisResp == null) { |
176 | | - Builder emptyFeatureRowBuilder = FeatureRow.newBuilder() |
177 | | - .setFeatureSet(String.format("%s:%s", featureSet.getName(), featureSet.getVersion())) |
178 | | - .addAllFields(redisKeys.get(i).getEntitiesList()) |
179 | | - .setEventTimestamp(Timestamp.newBuilder().setSeconds(0).build()); |
180 | | - for (String requestedColumn : requestedColumns) { |
181 | | - emptyFeatureRowBuilder.addFields(Field.newBuilder().setName(requestedColumn)); |
182 | | - } |
183 | | - featureRows.add(emptyFeatureRowBuilder.build()); |
184 | | - } else { |
185 | | - FeatureRow featureRow = FeatureRow.parseFrom(jedisResp); |
186 | | - List<Field> fields = featureRow.getFieldsList().stream() |
187 | | - .filter(f -> requestedColumns.contains(f.getName())).collect(Collectors.toList()); |
188 | | - featureRows.add(FeatureRow.newBuilder() |
189 | | - .addAllFields(redisKeys.get(i).getEntitiesList()) |
190 | | - .addAllFields(fields) |
191 | | - .setEventTimestamp(featureRow.getEventTimestamp()) |
192 | | - .setFeatureSet(String.format("%s:%s", featureSet.getName(), featureSet.getVersion())) |
193 | | - .build()); |
194 | | - } |
| 175 | + featureRows.add( |
| 176 | + buildFeatureRow(jedisResps.get(i), featureSetName, redisKeys.get(i).getEntitiesList(), |
| 177 | + requestedColumns)); |
195 | 178 | } |
196 | 179 | return featureRows; |
197 | 180 | } |
198 | 181 | } |
199 | 182 |
|
| 183 | + /** |
| 184 | + * Build a featureRow given the request and the |
| 185 | + * @param jedisResponse |
| 186 | + * @param featureSet |
| 187 | + * @param entities |
| 188 | + * @param requestedColumns |
| 189 | + * @return |
| 190 | + * @throws InvalidProtocolBufferException |
| 191 | + */ |
| 192 | + private FeatureRow buildFeatureRow(byte[] jedisResponse, String featureSet, List<Field> entities, |
| 193 | + List<String> requestedColumns) throws InvalidProtocolBufferException { |
| 194 | + Builder featureRowBuilder = FeatureRow.newBuilder() |
| 195 | + .setFeatureSet(featureSet) |
| 196 | + .addAllFields(entities) |
| 197 | + .setEventTimestamp(Timestamp.newBuilder().setSeconds(0).build()); |
| 198 | + |
| 199 | + if (jedisResponse == null) { |
| 200 | + for (String requestedColumn : requestedColumns) { |
| 201 | + featureRowBuilder.addFields(Field.newBuilder().setName(requestedColumn)); |
| 202 | + } |
| 203 | + return featureRowBuilder.build(); |
| 204 | + } |
| 205 | + FeatureRow featureRow = FeatureRow.parseFrom(jedisResponse); |
| 206 | + List<Field> fields = featureRow.getFieldsList().stream() |
| 207 | + .filter(f -> requestedColumns.contains(f.getName())).collect(Collectors.toList()); |
| 208 | + return featureRowBuilder |
| 209 | + .addAllFields(entities) |
| 210 | + .addAllFields(fields) |
| 211 | + .setEventTimestamp(featureRow.getEventTimestamp()) |
| 212 | + .setFeatureSet(featureSet) |
| 213 | + .build(); |
| 214 | + } |
| 215 | + |
200 | 216 | /** |
201 | 217 | * Send a list of get request as an mget |
202 | 218 | * |
|
0 commit comments