package edu.washington.escience.myria.parallel.ipc;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableSet;
import edu.washington.escience.myria.parallel.ipc.IPCEvent.EventType;
import edu.washington.escience.myria.util.concurrent.ReentrantSpinLock;
/**
* A simple InputBuffer implementation using bag semantic. The number of data held in this InputBuffer can be as large
* as {@link Integer.MAX_VALUE}.
*
* @param <PAYLOAD> the type of application defined data the input buffer is going to hold.
* */
public class SimpleBagInputBuffer<PAYLOAD> extends BagInputBufferAdapter<PAYLOAD> {
/**
* new input data.
* */
public static final EventType NEW_INPUT_DATA = new EventType("new input data");
/**
* serialize the events.
* */
private final ReentrantSpinLock newInputSerializeLock = new ReentrantSpinLock();
/**
* the buffer empty event.
* */
private final IPCEvent newInputEvent =
new IPCEvent() {
@Override
public Object getAttachment() {
return SimpleBagInputBuffer.this;
}
@Override
public EventType getType() {
return NEW_INPUT_DATA;
}
};
/**
* Fire a new input event. All the new arrival event listeners will be notified.
*
* New input event listeners are executed by trigger threads.
* */
protected final void fireNewInput() {
newInputSerializeLock.lock();
try {
for (IPCEventListener l : newArrivalListeners) {
l.triggered(newInputEvent);
}
} finally {
newInputSerializeLock.unlock();
}
}
@Override
protected final void postOffer(final IPCMessage.StreamData<PAYLOAD> e, final boolean isSucceed) {
if (isSucceed) {
fireNewInput();
}
}
/**
* new data event listeners.
* */
private final ConcurrentLinkedQueue<IPCEventListener> newArrivalListeners;
/**
* logger.
* */
static final Logger LOGGER = LoggerFactory.getLogger(SimpleBagInputBuffer.class);
/**
* @param owner the owner IPC pool.
* @param remoteChannelIDs from which channels, the data will input.
* */
public SimpleBagInputBuffer(
final IPCConnectionPool owner, final ImmutableSet<StreamIOChannelID> remoteChannelIDs) {
super(owner, remoteChannelIDs);
newArrivalListeners = new ConcurrentLinkedQueue<IPCEventListener>();
}
/**
* {@inheritDoc}.
*
* Only new data events is supported
* */
@Override
public final void addListener(final EventType t, final IPCEventListener l) {
if (t == NEW_INPUT_DATA) {
newArrivalListeners.add(l);
}
}
}