package com.activequant.backtesting; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.log4j.Logger; import com.activequant.domainmodel.streaming.StreamEvent; import com.activequant.domainmodel.streaming.StreamEventIterator; /** * * Fast Streamer takes a set of stream iterators and replays events * from these iterators in their chronological order. * * @author GhostRider * */ public class FastStreamer { private final Logger log = Logger.getLogger(FastStreamer.class); class FastStreamEventContainer implements Comparable<FastStreamEventContainer> { private final int internalStreamId; private StreamEvent streamEvent; FastStreamEventContainer(int streamId) { this.internalStreamId = streamId; } public int compareTo(FastStreamEventContainer other){ if(streamEvent==null || other.streamEvent==null)return -1; return streamEvent.getTimeStamp().compareTo(other.streamEvent.getTimeStamp()); } } private List<FastStreamEventContainer> fastQueue = new ArrayList<FastStreamEventContainer>(); private final FastStreamEventContainer[] containers; private final StreamEventIterator<StreamEvent>[] iterators; public FastStreamer( StreamEventIterator<StreamEvent>[] it) { this.iterators = it; // initialize also the headstart data. containers = new FastStreamEventContainer[it.length]; for (int i = 0; i < it.length; i++) { if (it[i].hasNext()) { StreamEvent payload = it[i].next(); if(containers[i] == null) containers[i] = new FastStreamEventContainer(i); FastStreamEventContainer fs = containers[i]; fs.streamEvent=payload; fastQueue.add(fs); } } // sort all events once. Collections.sort(fastQueue); } /** * Fetches the next stream event from the pipe. * @return */ public StreamEvent getOneFromPipes() { StreamEvent ret = null; if(!fastQueue.isEmpty()){ FastStreamEventContainer event = fastQueue.get(0); if(event==null)return null; fastQueue.remove(0); ret = event.streamEvent; if(iterators[event.internalStreamId].hasNext()) { StreamEvent payload = iterators[event.internalStreamId].next(); FastStreamEventContainer newEvent = new FastStreamEventContainer(event.internalStreamId); newEvent.streamEvent=payload; fastQueue.add(newEvent); Collections.sort(fastQueue); // // dumpQueue(); } // log.info(ret.getTimeStamp().getNanoseconds() + " - " + ret.getTimeStamp().getDate() + " - " + ret.toString()); } return ret; } private void dumpQueue(){ for(FastStreamEventContainer ec : fastQueue) { System.out.println(ec.streamEvent.getTimeStamp().getNanoseconds() + " - " + ec.streamEvent.getTimeStamp().getDate()); } } public boolean moreDataInPipe() { for (StreamEventIterator<StreamEvent> it : iterators) if (it.hasNext()) return true; return false; } }