/** * Publish all the batched writes so they can all be seen by the consumer stage * @param pipe Pipe target */ public static <S extends MessageSchema<S>> void publishWritesBatched(Pipe<S> pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //single length field still needs to move this value up, so this is always done //in most cases this is redundant pipe.blobWriteLastConsumedPos = pipe.blobRingHead.byteWorkingHeadPos.value; publishHeadPositions(pipe); }
/** * Publish all the batched writes so they can all be seen by the consumer stage * @param pipe Pipe target */ public static <S extends MessageSchema<S>> void publishWritesBatched(Pipe<S> pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //single length field still needs to move this value up, so this is always done //in most cases this is redundant pipe.blobWriteLastConsumedPos = pipe.blobRingHead.byteWorkingHeadPos.value; publishHeadPositions(pipe); }
/** * Checks if outgoing pipe has room for low level fragment write of the given size. * @param pipe Pipe target * @param size int size from as defined in FROM * @return boolean true if there is room */ public static <S extends MessageSchema<S>> boolean hasRoomForWrite(Pipe<S> pipe, int size) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //This holds the last known state of the tail position, if its sufficiently far ahead it indicates that //we do not need to fetch it again and this reduces contention on the CAS with the reader. //This is an important performance feature of the low level API and should not be modified. return roomToLowLevelWrite(pipe, pipe.llRead.llwConfirmedPosition+size); }
/** * Publish all the batched writes so they can all be seen by the consumer stage * @param pipe Pipe target */ public static <S extends MessageSchema<S>> void publishWritesBatched(Pipe<S> pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //single length field still needs to move this value up, so this is always done //in most cases this is redundant pipe.blobWriteLastConsumedPos = pipe.blobRingHead.byteWorkingHeadPos.value; publishHeadPositions(pipe); }
/** * Checks if outgoing pipe has room for low level fragment write of the given size. * @param pipe Pipe target * @param size int size from as defined in FROM * @return boolean true if there is room */ public static <S extends MessageSchema<S>> boolean hasRoomForWrite(Pipe<S> pipe, int size) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //This holds the last known state of the tail position, if its sufficiently far ahead it indicates that //we do not need to fetch it again and this reduces contention on the CAS with the reader. //This is an important performance feature of the low level API and should not be modified. long temp = pipe.llRead.llwConfirmedPosition+size; return roomToLowLevelWrite(pipe, temp); }
/** * Low level API for publish for new fragment. Must be called in order for consumer to see fragment. * @param pipe */ public static <S extends MessageSchema<S>> int publishWrites(Pipe<S> pipe) { notifyPubListener(pipe.pubListeners); assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //happens at the end of every fragment int consumed = writeTrailingCountOfBytesConsumed(pipe); //increment because this is the low-level API calling publishWritesBatched(pipe); return consumed; }
/** * Low level API for publish for new fragment. Must be called in order for consumer to see fragment. * @param pipe */ public static <S extends MessageSchema<S>> int publishWrites(Pipe<S> pipe) { notifyPubListener(pipe.pubListeners); assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //happens at the end of every fragment int consumed = writeTrailingCountOfBytesConsumed(pipe); //increment because this is the low-level API calling publishWritesBatched(pipe); return consumed; }
/** * Checks the specified pipe to see if there is room to write * @param pipe pipe to examine * @param <S> MessageSchema to extend * @return <code>true</code> if pipe has room to write else <code>false</code> */ public static <S extends MessageSchema<S>> boolean hasRoomForWrite(Pipe<S> pipe) { assert(null != pipe.slabRing) : "Pipe must be init before use"; assert(null != pipe.llRead) : "Expected pipe to be setup for low level use."; assert(Pipe.singleThreadPerPipeWrite(pipe.id)); long temp = pipe.llRead.llwConfirmedPosition+FieldReferenceOffsetManager.maxFragmentSize(Pipe.from(pipe)); return roomToLowLevelWrite(pipe, temp); }
/** * Low level API for publish for new fragment. Must be called in order for consumer to see fragment. * @param pipe */ public static <S extends MessageSchema<S>> int publishWrites(Pipe<S> pipe) { notifyPubListener(pipe.slabRingHead.workingHeadPos.value, pipe.pubListeners); assert(Pipe.singleThreadPerPipeWrite(pipe.id)); //happens at the end of every fragment int consumed = writeTrailingCountOfBytesConsumed(pipe); //increment because this is the low-level API calling publishWritesBatched(pipe); return consumed; }
/** * Checks the specified pipe to see if there is room to write * @param pipe pipe to examine * @param <S> MessageSchema to extend * @return <code>true</code> if pipe has room to write else <code>false</code> */ public static <S extends MessageSchema<S>> boolean hasRoomForWrite(Pipe<S> pipe) { assert(null != pipe.slabRing) : "Pipe must be init before use"; assert(null != pipe.llRead) : "Expected pipe to be setup for low level use."; assert(Pipe.singleThreadPerPipeWrite(pipe.id)); return roomToLowLevelWrite(pipe, pipe.llRead.llwConfirmedPosition+FieldReferenceOffsetManager.maxFragmentSize(Pipe.from(pipe))); }
/** * This sends a poison pill. Any pipe that receives this pill shuts down and sends the pill to any pipes downstream of them * @param pipe to send pill */ public static void publishEOF(Pipe pipe) { int i = pipe.pubListeners.length; while (--i>=0) { ((PipePublishListener)(pipe.pubListeners[i])).published(); } assert(Pipe.singleThreadPerPipeWrite(pipe.id)); StackStateWalker.writeEOF(pipe); Pipe.publishWorkingHeadPosition(pipe, pipe.ringWalker.nextWorkingHead = pipe.ringWalker.nextWorkingHead + Pipe.EOF_SIZE); }
/** * Check to see if specified pipe has room to write * @param pipe to be checked * @return <code>true</code> if pipe has room else <code>false</code> */ public static boolean hasRoomForWrite(Pipe pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(pipe!=null); assert(Pipe.isInit(pipe)); assert(pipe.usingHighLevelAPI); return StackStateWalker.hasRoomForFragmentOfSizeX(pipe, pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - FieldReferenceOffsetManager.maxFragmentSize( Pipe.from(pipe)))); }
/** * Check to see if specified pipe has room to write * @param pipe to be checked * @return <code>true</code> if pipe has room else <code>false</code> */ public static boolean hasRoomForWrite(Pipe pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(pipe!=null); assert(Pipe.isInit(pipe)); assert(pipe.usingHighLevelAPI); return StackStateWalker.hasRoomForFragmentOfSizeX(pipe, pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - FieldReferenceOffsetManager.maxFragmentSize( Pipe.from(pipe)))); }
/** * Check to see if specified pipe has room to write * @param pipe to be checked * @return <code>true</code> if pipe has room else <code>false</code> */ public static boolean hasRoomForWrite(Pipe pipe) { assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(pipe!=null); assert(Pipe.isInit(pipe)); assert(pipe.usingHighLevelAPI); return StackStateWalker.hasRoomForFragmentOfSizeX(pipe, pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - FieldReferenceOffsetManager.maxFragmentSize( Pipe.from(pipe)))); }
/** * Confirm low level write, Must be called after every fragment write to move cursor to next fragment to write * @param output * @return long position */ public static <S extends MessageSchema<S>> long confirmLowLevelWrite(Pipe<S> output) { //helper method always uses the right size but that value needs to be found so its a bit slower than if you already knew the size and passed it in assert(Pipe.singleThreadPerPipeWrite(output.id)); assert((output.llRead.llwConfirmedPosition+output.slabMask) <= Pipe.workingHeadPosition(output)) : " confirmed writes must be less than working head position writes:" +(output.llRead.llwConfirmedPosition+output.slabMask)+" workingHead:"+Pipe.workingHeadPosition(output)+ " \n CHECK that Pipe is written same fields as message defines and skips none!"; return output.llRead.llwConfirmedPosition += Pipe.sizeOf(output, output.slabRing[lastConfirmedWritePosition(output)]); }
/** * This sends a poison pill. Any pipe that receives this pill shuts down and sends the pill to any pipes downstream of them * @param pipe to send pill */ public static void publishEOF(Pipe pipe) { int i = pipe.pubListeners.length; while (--i>=0) { ((PipePublishListener)(pipe.pubListeners[i])).published(Pipe.workingHeadPosition(pipe)); } assert(Pipe.singleThreadPerPipeWrite(pipe.id)); StackStateWalker.writeEOF(pipe); Pipe.publishWorkingHeadPosition(pipe, pipe.ringWalker.nextWorkingHead = pipe.ringWalker.nextWorkingHead + Pipe.EOF_SIZE); }
/** * Confirm low level write, Must be called after every fragment write to move cursor to next fragment to write * @param output * @return long position */ public static <S extends MessageSchema<S>> long confirmLowLevelWrite(Pipe<S> output) { //helper method always uses the right size but that value needs to be found so its a bit slower than if you already knew the size and passed it in assert(Pipe.singleThreadPerPipeWrite(output.id)); assert((output.llRead.llwConfirmedPosition+output.slabMask) <= Pipe.workingHeadPosition(output)) : " confirmed writes must be less than working head position writes:" +(output.llRead.llwConfirmedPosition+output.slabMask)+" workingHead:"+Pipe.workingHeadPosition(output)+ " \n CHECK that Pipe is written same fields as message defines and skips none!"; return output.llRead.llwConfirmedPosition += Pipe.sizeOf(output, output.slabRing[lastConfirmedWritePosition(output)]); }
/** * Return true if there is room for the desired fragment in the output buffer. * Places working head in place for the first field to be written (eg after the template Id, which is written by this method) * */ public static boolean tryWriteFragment(Pipe pipe, final int fragmentId) { assert(null!=pipe); assert(fragmentId<Pipe.from(pipe).fragDataSize.length) : "Is this pipe for the schema holding this message?"; assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(Pipe.isInit(pipe)) : "Pipe must be initialized before use: "+pipe+" call the method initBuffers"; return StackStateWalker.tryWriteFragment0(pipe, fragmentId, Pipe.from(pipe).fragDataSize[fragmentId], pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - Pipe.from(pipe).fragDataSize[fragmentId])); }
/** * Return true if there is room for the desired fragment in the output buffer. * Places working head in place for the first field to be written (eg after the template Id, which is written by this method) * */ public static boolean tryWriteFragment(Pipe pipe, final int fragmentId) { assert(fragmentId<Pipe.from(pipe).fragDataSize.length) : "Is this pipe for the schema holding this message?"; assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(null!=pipe); assert(Pipe.isInit(pipe)) : "Pipe must be initialized before use: "+pipe+" call the method initBuffers"; return StackStateWalker.tryWriteFragment0(pipe, fragmentId, Pipe.from(pipe).fragDataSize[fragmentId], pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - Pipe.from(pipe).fragDataSize[fragmentId])); }
/** * Return true if there is room for the desired fragment in the output buffer. * Places working head in place for the first field to be written (eg after the template Id, which is written by this method) * */ public static boolean tryWriteFragment(Pipe pipe, final int fragmentId) { assert(null!=pipe); assert(fragmentId<Pipe.from(pipe).fragDataSize.length) : "Is this pipe for the schema holding this message?"; assert(Pipe.singleThreadPerPipeWrite(pipe.id)); assert(Pipe.isInit(pipe)) : "Pipe must be initialized before use: "+pipe+" call the method initBuffers"; return StackStateWalker.tryWriteFragment0(pipe, fragmentId, Pipe.from(pipe).fragDataSize[fragmentId], pipe.ringWalker.nextWorkingHead - (pipe.sizeOfSlabRing - Pipe.from(pipe).fragDataSize[fragmentId])); }