com.javanut.pronghorn.pipe.stream.StreamingVisitorReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pronghorn-pipes Show documentation
Show all versions of pronghorn-pipes Show documentation
Ring buffer based queuing utility for applications that require high performance and/or a small
footprint. Well suited for embedded and stream based processing.
package com.javanut.pronghorn.pipe.stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.javanut.pronghorn.pipe.FieldReferenceOffsetManager;
import com.javanut.pronghorn.pipe.Pipe;
import com.javanut.pronghorn.pipe.token.TokenBuilder;
import com.javanut.pronghorn.pipe.token.TypeMask;
public class StreamingVisitorReader {
private static final Logger log = LoggerFactory.getLogger(StreamingVisitorReader.class);
private final StreamingReadVisitor visitor;
private final Pipe> inputRing;
final FieldReferenceOffsetManager from;
private final LowLevelStateManager navState;
private final boolean processUTF8;
//TODO: B, this does not work with preamble of any size. is preamble a feature we really want to continue supporting in all case?
public StreamingVisitorReader(Pipe> inputRing, StreamingReadVisitor visitor, boolean processUTF8) {
this.inputRing = inputRing;
this.visitor = visitor;
this.processUTF8 = processUTF8;
this.from = Pipe.from(inputRing);
this.navState = new LowLevelStateManager(from);
}
public StreamingVisitorReader(Pipe inputRing, StreamingReadVisitor visitor) {
this(inputRing, visitor, true);
}
//TODO: these 3 need to be turned into static.
public void startup() {
this.visitor.startup();
}
public void shutdown() {
this.visitor.shutdown();
}
public void run() {
while (!visitor.paused() && Pipe.hasContentToRead(inputRing)) {
int startPos;
int cursor;
if (LowLevelStateManager.isStartNewMessage(navState)) {
//start new message
cursor = Pipe.takeMsgIdx(inputRing);
if (cursor<0) {
visitor.shutdown();
Pipe.confirmLowLevelRead(inputRing, Pipe.EOF_SIZE);
Pipe.releaseReadLock(inputRing);
return;
}
startPos = 1;//new message so skip over this messageId field
visitor.visitTemplateOpen(from.fieldNameScript[cursor], from.fieldIdScript[cursor]);
} else {
cursor = LowLevelStateManager.activeCursor(navState);
startPos = 0;//this is not a new message so there is no id to jump over.
}
int dataSize = Pipe.sizeOf(inputRing, cursor);
//must the next read position forward by the size of this fragment so next time we confirm that there is a fragment to read.
Pipe.confirmLowLevelRead(inputRing, dataSize);
//visit all the fields in this fragment
processFragment(startPos, cursor);
//move the position up but exclude the one byte that we already added on
Pipe.setWorkingTailPosition(inputRing, Pipe.getWorkingTailPosition(inputRing)+ (dataSize-startPos) - 1 );//Subtract one so release reads can get the byte count
Pipe.releaseReadLock(inputRing);
}
}
private void processFragment(int startPos, final int fragmentCursor) {
final int fieldsInFragment = from.fragScriptSize[fragmentCursor];
final String[] fieldNameScript = from.fieldNameScript;
final long[] fieldIdScript = from.fieldIdScript;
final int[] depth = from.fragDepth;
int i = startPos;
int idx = 0; //TODO: remove this and use the standard low level take methods.
while (i0);
}
}
} while (++fieldCursor=0) : "Optional strings are NOT supported for this type";
visitor.visitASCII(name, id, (CharSequence) Pipe.readASCII(inputRing, visitor.targetASCII(name, id), meta, len));
}
private void processTextASCIIOptional(String name, final int idx, int fieldCursor, long id) {
int meta = Pipe.readByteArraMetaData(idx, inputRing);
int len = Pipe.readByteArrayLength(idx, inputRing);
if (len>0) { //a negative length is a null and zero there is no work to do
visitor.visitASCII(name, id, (CharSequence) Pipe.readASCII(inputRing, visitor.targetASCII(name, id), meta, len));
}
}
private void processTextUTF8(String name, final int idx, int fieldCursor, long id) {
int meta = Pipe.readByteArraMetaData(idx, inputRing);
int len = Pipe.readByteArrayLength(idx, inputRing);
assert(len>=0) : "Optional strings are NOT supported for this type";
visitor.visitUTF8(name, id, (CharSequence) Pipe.readUTF8(inputRing, visitor.targetUTF8(name, id), meta, len));
}
private void processTextUTF8Optional(String name, final int idx, int fieldCursor, long id) {
int meta = Pipe.readByteArraMetaData(idx, inputRing);
int len = Pipe.readByteArrayLength(idx, inputRing);
if (len>0) { //a negative length is a null and zero there is no work to do
visitor.visitUTF8(name, id, (CharSequence) Pipe.readUTF8(inputRing, visitor.targetUTF8(name, id), meta, len));
}
}
private void processByteVector(String name, final int idx, int fieldCursor, long id) {
int meta = Pipe.readByteArraMetaData(idx, inputRing);
int len = Pipe.readByteArrayLength(idx, inputRing);
if (len>=0) {
visitor.visitBytes(name, id, Pipe.readBytes(inputRing, visitor.targetBytes(name, id, len), meta, len));
} else {
//len of -1 is a null not a zero length vector,
//NOTE: visitor does not yet support null;
}
}
private void processByteVectorOptional(String name, int idx, int fieldCursor, long id) {
int meta = Pipe.readByteArraMetaData(idx, inputRing);
int len = Pipe.readByteArrayLength(idx, inputRing);
if (len>0) { //a negative length is a null and zero there is no work to do
visitor.visitBytes(name, id, Pipe.readBytes(inputRing, visitor.targetBytes(name, id, len), meta, len));
}
}
private void processDictionary() {
{
log.debug("dictionary operation discovered, TODO: add this to the vistor to be supported");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy