/** * Called from the {@link DriverConductor}. * * @param now in nanoseconds * @param statusMessageTimeout for sending of Status Messages. */ void trackRebuild(final long now, final long statusMessageTimeout) { long minSubscriberPosition = Long.MAX_VALUE; long maxSubscriberPosition = Long.MIN_VALUE; for (final ReadablePosition subscriberPosition : subscriberPositions) { final long position = subscriberPosition.getVolatile(); minSubscriberPosition = Math.min(minSubscriberPosition, position); maxSubscriberPosition = Math.max(maxSubscriberPosition, position); } final long rebuildPosition = Math.max(this.rebuildPosition.get(), maxSubscriberPosition); final long hwmPosition = this.hwmPosition.getVolatile(); final long scanOutcome = lossDetector.scan( termBuffers[indexByPosition(rebuildPosition, positionBitsToShift)], rebuildPosition, hwmPosition, now, termLengthMask, positionBitsToShift, initialTermId); final int rebuildTermOffset = (int) rebuildPosition & termLengthMask; final long newRebuildPosition = (rebuildPosition - rebuildTermOffset) + rebuildOffset(scanOutcome); this.rebuildPosition.proposeMaxOrdered(newRebuildPosition); final long ccOutcome = congestionControl.onTrackRebuild( now, minSubscriberPosition, nextSmPosition, hwmPosition, rebuildPosition, newRebuildPosition, lossFound(scanOutcome)); final int window = CongestionControlUtil.receiverWindowLength(ccOutcome); final long threshold = CongestionControlUtil.positionThreshold(window); if (CongestionControlUtil.shouldForceStatusMessage(ccOutcome) || (now > (lastStatusMessageTimestamp + statusMessageTimeout)) || (minSubscriberPosition > (nextSmPosition + threshold))) { scheduleStatusMessage(now, minSubscriberPosition, window); cleanBufferTo(minSubscriberPosition - (termLengthMask + 1)); } }
private boolean isDrained() { long minSubscriberPosition = Long.MAX_VALUE; for (final ReadablePosition subscriberPosition : subscriberPositions) { minSubscriberPosition = Math.min(minSubscriberPosition, subscriberPosition.getVolatile()); } return minSubscriberPosition >= rebuildPosition.get(); }
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; } }