package resa.evaluation.simulate; import backtype.storm.Config; import backtype.storm.serialization.SerializationFactory; import backtype.storm.task.TopologyContext; import backtype.storm.topology.BasicOutputCollector; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.tuple.Tuple; import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.KryoSerializable; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import resa.examples.wc.WordCountTopology; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.UUID; /** * Created by ding on 14-7-29. */ public class DataLoader extends WordCountTopology.WordCount { private static class WordCountDB implements KryoSerializable { private long size; public WordCountDB(long size) { this.size = size; } public WordCountDB() { } @Override public void write(Kryo kryo, Output output) { String s = UUID.randomUUID().toString(); output.writeLong(size); long total = output.total(); while (output.total() - total < size) { output.writeBoolean(true); output.writeString(s); output.writeInt((int) (Math.random() * Integer.MAX_VALUE)); } output.writeBoolean(false); } @Override public void read(Kryo kryo, Input input) { size = input.readLong(); while (input.readBoolean()) { // for (int i = 0; i < 1; i++) { // Math.atan(Math.sqrt(Math.random() * Integer.MAX_VALUE)); // } input.readString(); input.readInt(); } } } @Override public void prepare(Map stormConf, TopologyContext context) { if (context.getTaskData("pattern") == null) { try { generateData(stormConf, context); } catch (IOException e) { e.printStackTrace(); } } else { Path file = getPath(stormConf, context); if (!Files.exists(file)) { context.getSharedExecutor().submit(() -> { Kryo kryo = SerializationFactory.getKryo(stormConf); try (Output out = new Output(Files.newOutputStream(getPath(stormConf, context)))) { out.writeInt(1); out.writeString("pattern"); WordCountDB db = (WordCountDB) context.getTaskData("pattern"); kryo.writeClass(out, db.getClass()); db.write(kryo, out); } catch (IOException e) { e.printStackTrace(); } }); } } } public void generateData(Map stormConf, TopologyContext context) throws IOException { List<Double> dataSizes = (List<Double>) stormConf.get("dataSizes"); long dataSize = (long) (dataSizes.get(context.getThisTaskIndex()) * 600); Kryo kryo = SerializationFactory.getKryo(stormConf); WordCountDB db = new WordCountDB(dataSize); try (Output out = new Output(Files.newOutputStream(getPath(stormConf, context)))) { out.writeInt(1); out.writeString("pattern"); kryo.writeClass(out, db.getClass()); db.write(kryo, out); } System.out.println("Load dataSize is " + dataSize); context.setTaskData("pattern", db); } private Path getPath(Map<String, Object> conf, TopologyContext context) { Path loaclDataPath = Paths.get((String) conf.get(Config.STORM_LOCAL_DIR), "data", context.getStormId()); if (!Files.exists(loaclDataPath)) { try { Files.createDirectories(loaclDataPath); } catch (FileAlreadyExistsException e) { } catch (IOException e) { loaclDataPath = null; } } if (loaclDataPath != null) { loaclDataPath = loaclDataPath.resolve(String.format("task-%03d.data", context.getThisTaskId())); } return loaclDataPath; } @Override public void execute(Tuple input, BasicOutputCollector collector) { // long now = System.currentTimeMillis(); // do { for (int i = 0; i < 10; i++) { Math.atan(Math.sqrt(Math.random() * Integer.MAX_VALUE)); } // } while (System.currentTimeMillis() - now > 1); } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { } }