/** * @author Koushik Sinha * Last modified: 06/01/2014 * * The ChannelBuffer class implements the creation, * and deletion of channels as well as retrieval of * messages from a specific channel. * */ package qa.qcri.aidr.output.getdata; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.collections.Buffer; import org.apache.commons.collections.BufferUtils; import org.apache.commons.collections.buffer.CircularFifoBuffer; import org.apache.log4j.Logger; public class ChannelBuffer { public static int MAX_BUFFER_SIZE = 2000; // number of elements the buffer will hold at any time public static int MAX_FETCH_SIZE = 2000; // max. number of elements to fetch in one op private String channelName = null; private long lastAddTime; private Buffer messageBuffer = null; int size = 0; private Boolean publiclyListed = true; private static Logger logger = Logger.getLogger(ChannelBuffer.class); public ChannelBuffer(final String name, final int bufferSize) { this.channelName = name; this.messageBuffer = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(bufferSize)); this.size = bufferSize; } public ChannelBuffer(final String name) { this.channelName = name; } public void createChannelBuffer() { this.messageBuffer = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(MAX_BUFFER_SIZE)); this.size = MAX_BUFFER_SIZE; } public void createChannelBuffer(final int bufferSize) { this.messageBuffer = BufferUtils.synchronizedBuffer(new CircularFifoBuffer(bufferSize)); this.size = bufferSize; } public void setPubliclyListed(Boolean publiclyListed) { this.publiclyListed = publiclyListed; } public Boolean getPubliclyListed() { return publiclyListed; } @SuppressWarnings("unchecked") public void addMessage(String msg) { try { //synchronized(this.messageBuffer) { messageBuffer.add(msg); lastAddTime = new Date().getTime(); } } catch (Exception e) { logger.error("Couldn't add message to buffer for channel: " + this.channelName); } } @SuppressWarnings("unchecked") public void addAllMessages(ArrayList<String> msgList) { try { //synchronized(this.messageBuffer) { messageBuffer.addAll(msgList); lastAddTime = new Date().getTime(); } } catch (Exception e) { logger.error("Couldn't add message to buffer for channel: " + this.channelName); } } @SuppressWarnings("unchecked") /** * @param msgCount: number of messages to return * @return Returns a list of messages sorted in ascending order of timestamp */ public List<String> getMessages(int msgCount) { //long startTime = System.currentTimeMillis(); List<String> tempList = null; try { synchronized(this.messageBuffer) { tempList = new ArrayList<String>(this.messageBuffer.size()); tempList.addAll(this.messageBuffer); } //logger.info("Copied data : " + tempList.size() + ", msgCount:messageBuffer.size = " + msgCount + ":" + messageBuffer.size()); if (msgCount >= tempList.size()) { return tempList; // optimization } // Otherwise, get the last msgCount elements, in oldest-first order // Collections.reverse(tempList); // in-situ reversal O(n) time List<String> returnList = new ArrayList<String>(msgCount); int index = Math.max(0, (tempList.size() - msgCount)); // from where to pick for (int i = index;i < tempList.size();i++) { returnList.add(tempList.get(i)); } //logger.info("Fetched size = " + msgCount + " from start loc = " + Math.max(0, (tempList.size() - msgCount))); return returnList; } catch (Exception e) { logger.error("Error in creating list out of buffered messages"); return null; } } public int getCurrentMsgCount() { return messageBuffer.size(); } public void deleteBuffer() { channelName = null; if (messageBuffer != null) { messageBuffer.clear(); messageBuffer = null; } } public void setChannelName(String name) { channelName = name; } public String getChannelName() { return channelName; } public long getLastAddTime() { return lastAddTime; } public int getMaxBufferSize() { return MAX_BUFFER_SIZE; } public int getMaxFetchSize() { return MAX_FETCH_SIZE; } public int getBufferSize() { return size; } }