All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.javanut.pronghorn.pipe.stream.StreamingVisitorReader Maven / Gradle / Ivy

Go to download

Ring buffer based queuing utility for applications that require high performance and/or a small footprint. Well suited for embedded and stream based processing.

There is a newer version: 1.1.27
Show newest version
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