package resa.examples.outdet;
import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
/**
* Created by ding on 14-3-14.
*/
public class Projection implements IRichBolt {
public static final String PROJECTION_ID_FIELD = "projectionId";
public static final String PROJECTION_VALUE_FIELD = "projectionValue";
private List<double[]> randomVectors;
private transient OutputCollector collector;
public Projection(List<double[]> randomVectors) {
this.randomVectors = randomVectors;
}
@Override
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
this.collector = collector;
}
@Override
public void execute(Tuple input) {
Object objId = input.getValueByField(ObjectSpout.ID_FILED);
Object time = input.getValueByField(ObjectSpout.TIME_FILED);
double[] v = (double[]) input.getValueByField(ObjectSpout.VECTOR_FILED);
IntStream.range(0, randomVectors.size()).forEach((i) -> {
collector.emit(input, new Values(objId, i, innerProduct(randomVectors.get(i), v), time));
});
collector.ack(input);
}
private static double innerProduct(double[] v1, double[] v2) {
if (v1.length != v2.length) {
throw new IllegalArgumentException();
}
return IntStream.range(0, v1.length).mapToDouble((i) -> v1[i] * v2[i]).sum();
}
@Override
public void cleanup() {
}
@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields(ObjectSpout.ID_FILED, PROJECTION_ID_FIELD,
PROJECTION_VALUE_FIELD, ObjectSpout.TIME_FILED));
}
@Override
public Map<String, Object> getComponentConfiguration() {
return null;
}
}