package uk.ac.imperial.lsds.seep.gc14.operator; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.nio.MappedByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.LinkedBlockingDeque; import uk.ac.imperial.lsds.seep.comm.serialization.DataTuple; import uk.ac.imperial.lsds.seep.comm.serialization.messages.TuplePayload; import uk.ac.imperial.lsds.seep.operator.StatelessOperator; public class Source implements StatelessOperator { private static final long serialVersionUID = 1L; /* * Get the information on the structure of processed tuples */ private DataTuple dataTupleStructure; /* * Members needed for parsing the data block-wise */ public final static String[] KEYS = "id,timestamp,value,property,plug_id,household_id,house_id".split(","); public final static String[] TYPES = "Long,Integer,Float,Integer,Integer,Integer,Integer".split(","); private BufferedReader reader = null; private int blockSize = -1; private List<DataTuple> block = new ArrayList<DataTuple>(); // data is now a field, so that it is accessible from outside processData() DataTuple data; int bufferSize = 5000000; @Override public void processData(DataTuple arg0) { //tuple schema stuff Map<String, Integer> mapper = api.getDataMapper(); data = new DataTuple(mapper, new TuplePayload()); //time control stuff int c = 0; long init = System.currentTimeMillis(); while(true){ c++; /** * READ FROM DISK */ try { DataTuple toSend = readNext(); toSend.getPayload().instrumentation_ts = System.currentTimeMillis(); if(toSend != null){ if(toSend.getInt("timestamp") > 1378339200){ System.out.println("DONE pass"); return; } api.send(toSend); } } catch (Exception e) { e.printStackTrace(); } //TIMING if((System.currentTimeMillis() - init) > 1000){ System.out.println("SRC "+c+" "); c = 0; init = System.currentTimeMillis(); } } } class DiskReader implements Runnable{ LinkedBlockingDeque<DataTuple> buffer; public DiskReader(LinkedBlockingDeque<DataTuple> buffer){ this.buffer = buffer; } @Override public void run() { // never stop while(true){ //just read from disk and inject into the deque try { buffer.putLast(readNext()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class Injector implements Runnable { private ArrayList<DataTuple> buffer = new ArrayList<DataTuple>(); private int downstreamId = 0; public Injector(ArrayList<DataTuple> buffer, int downstreamId){ // deep copy array for(int i = 0; i<buffer.size(); i++){ this.buffer.add(buffer.get(i)); } this.downstreamId = downstreamId; } public void run(){ int index = 0; while(true){ DataTuple output = buffer.get(index); index++; if(index == bufferSize-2){ index = 0; } api.send_toStreamId(output, downstreamId); } } } public DataTuple readNext() throws Exception { if (blockSize <= 0) { return readItem(); } if (block.isEmpty()) { int read = readBlock(); if (read == 0) return null; } DataTuple item = block.remove(0); return item; } protected int readBlock() throws Exception { block.clear(); int read = 0; for (int i = 0; i < blockSize; i++) { DataTuple item = readItem(); if (item != null) { block.add(item); read++; } else return read; } return read; } protected DataTuple readItem() throws Exception { // System.out.println("readItem()"); if (dataTupleStructure == null){ System.out.println("dataTupleStructure is null"); return null; } String line = reader.readLine(); // System.out.println(line); if (line == null) return null; Object[] values = new Object[KEYS.length]; int i = 0; int len = line.length(); int max = len - 1; int floating = 0; Long longVal = 0L; Float floatVal = 0f; for (int c = 0; c < len; c++) { char ch = line.charAt(c); if (ch == ',') { if (floating > 0) values[i] = hardCodedCast(i,String.valueOf(longVal + floatVal / floating)); else values[i] = hardCodedCast(i,String.valueOf(longVal)); longVal = 0L; floatVal = 0f; floating = 0; i++; if (ch == '\n'){ DataTuple output = data.newTuple(values); return output; } else{ continue; } } if (ch == '.') { floating = 1; continue; } if (floating > 0) { floatVal *= 10; floatVal += (ch - '0'); floating *= 10; } else { longVal *= 10; longVal += (ch - '0'); } if (c == max) { if (floating > 0) values[i] = hardCodedCast(i,String.valueOf(longVal + floatVal / floating)); else values[i] = hardCodedCast(i,String.valueOf(longVal)); DataTuple output = data.newTuple(values); return output; } } DataTuple output = data.newTuple(values); return output; } @Override public void processData(List<DataTuple> arg0) { } @Override public void setUp() { String filePath = null; int opId = api.getOperatorId(); if(opId == 0){ filePath = "file:///houses0-4.csv"; } else if(opId == 11){ filePath = "file:///houses5-9.csv"; } else if(opId == 12){ filePath = "file:///houses10-14.csv"; } else if(opId == 13){ filePath = "file:///houses15-19.csv"; } filePath = "file:///input.csv"; URL url; try { url = new URL(filePath); setUp(url); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private Object hardCodedCast(int i, String value) { switch (TYPES[i]) { case "Integer": return new Integer(value); case "Long": return new Long(value); case "Float": return new Float(value); default: return value; } } public void setUp(URL url) throws IOException { this.reader = new BufferedReader(new InputStreamReader(url.openStream())); if (blockSize > 0) { this.block = new ArrayList<DataTuple>(blockSize); } Map<String, Integer> mapper = api.getDataMapper(); this.dataTupleStructure = new DataTuple(mapper, new TuplePayload()); } public int getBlockSize() { return blockSize; } public void setBlockSize(int blockSize) { this.blockSize = blockSize; } class BufferedMemoryMapInputStreamAdapter extends BufferedInputStream{ public BufferedMemoryMapInputStreamAdapter(InputStream in) { super(in); } } class MemoryMapInputStreamAdapter extends InputStream{ MappedByteBuffer b = null; public MemoryMapInputStreamAdapter(MappedByteBuffer b){ this.b = b; } @Override public int read() throws IOException { return b.get(); } } }