com.javanut.pronghorn.pipe.stream.StreamingVisitorWriter 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 static com.javanut.pronghorn.pipe.Pipe.publishAllBatchedWrites;
import static com.javanut.pronghorn.pipe.Pipe.publishWrites;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import com.javanut.pronghorn.pipe.FieldReferenceOffsetManager;
import com.javanut.pronghorn.pipe.MessageSchema;
import com.javanut.pronghorn.pipe.Pipe;
import com.javanut.pronghorn.pipe.token.TokenBuilder;
import com.javanut.pronghorn.pipe.token.TypeMask;
public class StreamingVisitorWriter {
private StreamingWriteVisitor visitor;
private Pipe outputRing;
private FieldReferenceOffsetManager from;
private int maxFragmentSize;
private final LowLevelStateManager navState;
public StreamingVisitorWriter(Pipe outputRing, StreamingWriteVisitor visitor) {
this.visitor = visitor;
this.outputRing = outputRing;
this.from = Pipe.from(outputRing);
this.maxFragmentSize = FieldReferenceOffsetManager.maxFragmentSize(this.from);
this.navState = new LowLevelStateManager(from);
}
public boolean isAtBreakPoint() {
return LowLevelStateManager.isStartNewMessage(navState);
}
public void run() {
//write as long as its not posed and we have room to write any possible known fragment
while (!visitor.paused() && Pipe.hasRoomForWrite(outputRing, maxFragmentSize) ) {
int startPos;
int cursor;
if (LowLevelStateManager.isStartNewMessage(navState)) {
//start new message, visitor returns this new id to be written.
cursor = visitor.pullMessageIdx();
assert(isValidMessageStart(cursor, from));
if (cursor<0) {
Pipe.publishWrites(outputRing);
Pipe.publishAllBatchedWrites(outputRing);
return;
}
Pipe.addMsgIdx(outputRing, cursor);
startPos = 1;//new message so skip over this messageId field
//Beginning of template
//These name the message template but no need for them at this time
//String messageName = from.fieldNameScript[cursor];
//long messageId = from.fieldIdScript[cursor];
} else {
cursor = LowLevelStateManager.activeCursor(navState);
startPos = 0;//this is not a new message so there is no id to jump over.
}
//visit all the fields in this fragment
processFragment(startPos, cursor);
Pipe.confirmLowLevelWrite(outputRing, from.fragDataSize[cursor]);
publishWrites(outputRing);
}
publishAllBatchedWrites(outputRing);
}
private boolean isValidMessageStart(int cursor, FieldReferenceOffsetManager from) {
int i = from.messageStarts.length;
while (--i>=0) {
if (cursor == from.messageStarts[i]) {
return true;
}
}
return false;
}
public void startup() {
this.visitor.startup();
}
public void shutdown() {
this.visitor.shutdown();
}
private void processFragment(int startPos, int fragmentCursor) {
int fieldsInFragment = from.fragScriptSize[fragmentCursor];
int i = startPos;
final String[] fieldNameScript = from.fieldNameScript;
final long[] fieldIdScript = from.fieldIdScript;
final int[] depth = from.fragDepth;
//System.err.println("begin write of fragment "+from.fieldNameScript[cursor]+" "+cursor);
while (i0);
}
}
} while (++fieldCursor
© 2015 - 2025 Weber Informatics LLC | Privacy Policy