use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class PublicationImage method processPendingLoss.
/**
* Called from the {@link Receiver} thread to processing any pending loss of packets.
*
* @return number of work items processed.
*/
int processPendingLoss() {
int workCount = 0;
final long changeNumber = endLossChange;
if (changeNumber != lastLossChangeNumber) {
final int termId = lossTermId;
final int termOffset = lossTermOffset;
final int length = lossLength;
// LoadLoad required so previous loads don't move past version check below.
UNSAFE.loadFence();
if (changeNumber == beginLossChange) {
if (isReliable) {
channelEndpoint.sendNakMessage(controlAddress, sessionId, streamId, termId, termOffset, length);
nakMessagesSent.orderedIncrement();
} else {
final UnsafeBuffer termBuffer = termBuffers[indexByTerm(initialTermId, termId)];
if (tryFillGap(rawLog.metaData(), termBuffer, termId, termOffset, length)) {
lossGapFills.orderedIncrement();
}
}
lastLossChangeNumber = changeNumber;
workCount = 1;
}
}
return workCount;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class PublicationImage method cleanBufferTo.
private void cleanBufferTo(final long newCleanPosition) {
final long cleanPosition = this.cleanPosition;
final int bytesForCleaning = (int) (newCleanPosition - cleanPosition);
final UnsafeBuffer dirtyTerm = termBuffers[indexByPosition(cleanPosition, positionBitsToShift)];
final int termOffset = (int) cleanPosition & termLengthMask;
final int length = Math.min(bytesForCleaning, dirtyTerm.capacity() - termOffset);
if (length > 0) {
dirtyTerm.setMemory(termOffset, length, (byte) 0);
this.cleanPosition = cleanPosition + length;
}
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class PublicationImage method insertPacket.
/**
* Insert frame into term buffer.
*
* @param termId for the data packet to insert into the appropriate term.
* @param termOffset for the start of the packet in the term.
* @param buffer for the data packet to insert into the appropriate term.
* @param length of the data packet
* @return number of bytes applied as a result of this insertion.
*/
int insertPacket(final int termId, final int termOffset, final UnsafeBuffer buffer, final int length) {
final boolean isHeartbeat = isHeartbeat(buffer, length);
final long packetPosition = computePosition(termId, termOffset, positionBitsToShift, initialTermId);
final long proposedPosition = isHeartbeat ? packetPosition : packetPosition + length;
final long windowPosition = nextSmPosition;
if (!isFlowControlUnderRun(windowPosition, packetPosition) && !isFlowControlOverRun(windowPosition, proposedPosition)) {
if (isHeartbeat) {
heartbeatsReceived.orderedIncrement();
} else {
final UnsafeBuffer termBuffer = termBuffers[indexByPosition(packetPosition, positionBitsToShift)];
TermRebuilder.insert(termBuffer, termOffset, buffer, length);
}
hwmCandidate(proposedPosition);
}
return length;
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class SenderTest method shouldSendMultipleDataFramesAsHeartbeatsWhenIdle.
@Test
public void shouldSendMultipleDataFramesAsHeartbeatsWhenIdle() {
final StatusMessageFlyweight msg = mock(StatusMessageFlyweight.class);
when(msg.consumptionTermId()).thenReturn(INITIAL_TERM_ID);
when(msg.consumptionTermOffset()).thenReturn(0);
when(msg.receiverWindowLength()).thenReturn(ALIGNED_FRAME_LENGTH);
publication.onStatusMessage(msg, rcvAddress);
// publication.senderPositionLimit(
// flowControl.onStatusMessage(INITIAL_TERM_ID, 0, ALIGNED_FRAME_LENGTH, rcvAddress));
final UnsafeBuffer buffer = new UnsafeBuffer(ByteBuffer.allocateDirect(PAYLOAD.length));
buffer.putBytes(0, PAYLOAD);
termAppenders[0].appendUnfragmentedMessage(headerWriter, buffer, 0, PAYLOAD.length, null);
sender.doWork();
// should send ticks
assertThat(receivedFrames.size(), is(2));
receivedFrames.remove();
// skip setup & data frame
receivedFrames.remove();
currentTimestamp += Configuration.PUBLICATION_HEARTBEAT_TIMEOUT_NS - 1;
sender.doWork();
// should not send yet
assertThat(receivedFrames.size(), is(0));
currentTimestamp += 10;
sender.doWork();
// should send ticks
assertThat(receivedFrames.size(), greaterThanOrEqualTo(1));
dataHeader.wrap(receivedFrames.remove());
assertThat(dataHeader.frameLength(), is(0));
assertThat(dataHeader.termOffset(), is(offsetOfMessage(2)));
currentTimestamp += Configuration.PUBLICATION_HEARTBEAT_TIMEOUT_NS - 1;
sender.doWork();
// should not send yet
assertThat(receivedFrames.size(), is(0));
currentTimestamp += 10;
sender.doWork();
// should send ticks
assertThat(receivedFrames.size(), greaterThanOrEqualTo(1));
dataHeader.wrap(receivedFrames.remove());
assertThat(dataHeader.frameLength(), is(0));
assertThat(dataHeader.termOffset(), is(offsetOfMessage(2)));
}
use of org.agrona.concurrent.UnsafeBuffer in project Aeron by real-logic.
the class SenderTest method shouldSendSetupFrameOnChannelWhenTimeoutWithoutStatusMessage.
@Test
public void shouldSendSetupFrameOnChannelWhenTimeoutWithoutStatusMessage() throws Exception {
sender.doWork();
assertThat(receivedFrames.size(), is(1));
currentTimestamp += Configuration.PUBLICATION_SETUP_TIMEOUT_NS - 1;
sender.doWork();
assertThat(receivedFrames.size(), is(1));
currentTimestamp += 10;
sender.doWork();
assertThat(receivedFrames.size(), is(2));
setupHeader.wrap(new UnsafeBuffer(receivedFrames.remove()));
assertThat(setupHeader.frameLength(), is(SetupFlyweight.HEADER_LENGTH));
assertThat(setupHeader.initialTermId(), is(INITIAL_TERM_ID));
assertThat(setupHeader.activeTermId(), is(INITIAL_TERM_ID));
assertThat(setupHeader.streamId(), is(STREAM_ID));
assertThat(setupHeader.sessionId(), is(SESSION_ID));
assertThat(setupHeader.headerType(), is(HeaderFlyweight.HDR_TYPE_SETUP));
assertThat(setupHeader.flags(), is((short) 0));
assertThat(setupHeader.version(), is((short) HeaderFlyweight.CURRENT_VERSION));
}
Aggregations