com.javanut.pronghorn.pipe.PipeReader 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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.javanut.pronghorn.pipe.token.LOCUtil;
import com.javanut.pronghorn.pipe.token.TokenBuilder;
import com.javanut.pronghorn.pipe.token.TypeMask;
import java.io.DataOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* Public interface for applications desiring to consume data from a FAST feed.
* @author Nathan Tippy
*
*/
public class PipeReader {//TODO: B, build another static reader that does auto convert to the requested type.
public final static int POS_CONST_MASK = 0x7FFFFFFF;
public final static int OFF_MASK = FieldReferenceOffsetManager.RW_FIELD_OFF_MASK;
public final static int STACK_OFF_MASK = FieldReferenceOffsetManager.RW_STACK_OFF_MASK;
public final static int STACK_OFF_SHIFT = FieldReferenceOffsetManager.RW_STACK_OFF_SHIFT;
public final static int OFF_BITS = FieldReferenceOffsetManager.RW_FIELD_OFF_BITS;
public final static Logger log = LoggerFactory.getLogger(PipeReader.class);
public final static double[] powdi = new double[]{
1.0E64,1.0E63,1.0E62,1.0E61,1.0E60,1.0E59,1.0E58,1.0E57,1.0E56,1.0E55,1.0E54,1.0E53,1.0E52,1.0E51,1.0E50,1.0E49,1.0E48,1.0E47,1.0E46,1.0E45,1.0E44,1.0E43,1.0E42,1.0E41,1.0E40,1.0E39,1.0E38,1.0E37,1.0E36,1.0E35,1.0E34,1.0E33,
1.0E32,1.0E31,1.0E30,1.0E29,1.0E28,1.0E27,1.0E26,1.0E25,1.0E24,1.0E23,1.0E22,1.0E21,1.0E20,1.0E19,1.0E18,1.0E17,1.0E16,1.0E15,1.0E14,1.0E13,1.0E12,1.0E11,1.0E10,1.0E9,1.0E8,1.0E7,1000000.0,100000.0,10000.0,1000.0,100.0,10.0,
1.0,0.1,0.01,0.001,1.0E-4,1.0E-5,1.0E-6,1.0E-7,1.0E-8,1.0E-9,1.0E-10,1.0E-11,1.0E-12,1.0E-13,1.0E-14,1.0E-15,1.0E-16,1.0E-17,1.0E-18,1.0E-19,1.0E-20,1.0E-21,1.0E-22,1.0E-23,1.0E-24,1.0E-25,1.0E-26,1.0E-27,1.0E-28,1.0E-29,1.0E-30,1.0E-31,
0E-32,1.0E-33,1.0E-34,1.0E-35,1.0E-36,1.0E-37,1.0E-38,1.0E-39,1.0E-40,1.0E-41,0E-42,1.0E-43,1.0E-44,1.0E-45,1.0E-46,1.0E-47,1.0E-48,1.0E-49,1.0E-50,1.0E-51,1.0E-52,1.0E-53,1.0E-54,1.0E-55,1.0E-56,1.0E-57,1.0E-58,1.0E-59,1.0E-60,1.0E-61,1.0E-62,1.0E-63,1.0E-64
};
public final static float[] powfi = new float[]{
Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,1.0E38f,1.0E37f,1.0E36f,1.0E35f,1.0E34f,1.0E33f,
1.0E32f,1.0E31f,1.0E30f,1.0E29f,1.0E28f,1.0E27f,1.0E26f,1.0E25f,1.0E24f,1.0E23f,1.0E22f,1.0E21f,1.0E20f,1.0E19f,1.0E18f,1.0E17f,1.0E16f,1.0E15f,1.0E14f,1.0E13f,1.0E12f,1.0E11f,1.0E10f,1.0E9f,1.0E8f,1.0E7f,1000000.0f,100000.0f,10000.0f,1000.0f,100.0f,10.0f,
1.0f,0.1f,0.01f,0.001f,1.0E-4f,1.0E-5f,1.0E-6f,1.0E-7f,1.0E-8f,1.0E-9f,1.0E-10f,1.0E-11f,1.0E-12f,1.0E-13f,1.0E-14f,1.0E-15f,1.0E-16f,1.0E-17f,1.0E-18f,1.0E-19f,1.0E-20f,1.0E-21f,1.0E-22f,1.0E-23f,1.0E-24f,1.0E-25f,1.0E-26f,1.0E-27f,1.0E-28f,1.0E-29f,1.0E-30f,1.0E-31f,
0E-32f,1.0E-33f,1.0E-34f,1.0E-35f,1.0E-36f,1.0E-37f,1.0E-38f,1.0E-39f,1.0E-40f,1.0E-41f,0E-42f,1.0E-43f,1.0E-44f,1.0E-45f,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN,Float.NaN
};
public static > DataInputBlobReader inputStream(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc)+" b"+Integer.toBinaryString(loc);
DataInputBlobReader stream = Pipe.inputStream(pipe);
stream.openHighLevelAPIField(loc);
return stream;
}
/**
* Reads int from specified pipe
* @param pipe to read from
* @param loc location of int to read
* @return data from specified location
*/
public static int readInt(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional, TypeMask.GroupLength)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.readInt(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)]+(OFF_MASK&loc));
}
/**
* Reads int securely from specified pipe
* @param pipe to read from
* @param loc location of int to read
* @param clearValue value to replace previous int with
* @return data from specified location
*/
public static int readIntSecure(Pipe pipe, int loc, int clearValue) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional, TypeMask.GroupLength)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.readIntSecure(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)]+(OFF_MASK&loc),clearValue);
}
/**
* Reads short from specified pipe
* @param pipe to be read
* @param loc location of short to read
* @return data from specified location
*/
public static short readShort(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional)): "Value found "+LOCUtil.typeAsString(loc);
return (short)Pipe.readInt(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)]+(OFF_MASK&loc));
}
/**
* Reads byte from specified pipe
* @param pipe to be read
* @param loc location of byte to read
* @return data from specified location
*/
public static byte readByte(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional)): "Value found "+LOCUtil.typeAsString(loc);
return (byte)Pipe.readInt(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)]+(OFF_MASK&loc));
}
/**
* Reads long from specified pipe
* @param pipe to be read
* @param loc location of long to read
* @return data from specified location
*/
public static long readLong(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.LongSigned, TypeMask.LongSignedOptional, TypeMask.LongUnsigned, TypeMask.LongUnsignedOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.readLong(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] +(OFF_MASK&loc));
}
/**
* Reads double from specified pipe
* @param pipe to be read
* @param loc location of double to read
* @return data from specified location
*/
public static double readDouble(Pipe pipe, int loc) {
assert((loc&0x1E<>OFF_BITS)&TokenBuilder.MASK_TYPE);
return ((double)readDecimalMantissa(pipe,loc))*powdi[64 - readDecimalExponent(pipe,loc)];
}
/**
* Reads long bits from specified pipe and converts to double
* @param pipe to be read
* @param loc location of long bits to read
* @return double bits converted from long
*/
public static double readLongBitsToDouble(Pipe pipe, int loc) {
assert((loc&0x1C<>OFF_BITS)&TokenBuilder.MASK_TYPE);
return Double.longBitsToDouble(readLong(pipe,loc));
}
/**
* Reads float from specified pipe
* @param pipe to be read
* @param loc location of float to read
* @return data from specified location
*/
public static float readFloat(Pipe pipe, int loc) {
assert((loc&0x1E<>OFF_BITS)&TokenBuilder.MASK_TYPE);
return ((float)readDecimalMantissa(pipe,loc))*powfi[64 - readDecimalExponent(pipe,loc)];
}
/**
* Reads int bits from specified pipe and converts to float
* @param pipe to be read
* @param loc location of int bits to read
* @return float bits converted from int
*/
public static float readIntBitsToFloat(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Float.intBitsToFloat(readInt(pipe,loc));
}
/**
* Reads decimal exponent from specified pipe
* @param pipe to read from
* @param loc location to read from
* @return decimal
*/
public static int readDecimalExponent(Pipe pipe, int loc) {
assert((loc&0x1E<>OFF_BITS)&TokenBuilder.MASK_TYPE);
return Pipe.readInt(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc));
}
/**
* Reads decimal mantissa from specified pipe
* @param pipe to read from
* @param loc location to read from
* @return mantissa
*/
public static long readDecimalMantissa(Pipe pipe, int loc) {
assert((loc&0x1E<>OFF_BITS)&TokenBuilder.MASK_TYPE);
return Pipe.readLong(Pipe.slab(pipe), pipe.slabMask, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc) + 1);//plus one to skip over exponent
}
/**
* Checks specified pipe to see if charSeq and value at specific location are equal
* @param pipe pipe to be checked
* @param loc location of value to compare
* @param charSeq CharSequence to compare
* @return true
if the values are equal else false
*/
public static boolean isEqual(Pipe pipe, int loc, CharSequence charSeq) {
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
return Pipe.isEqual(pipe, charSeq, pos, PipeReader.readBytesLength(pipe,loc));
}
/**
* Reads ASCII from specified pipe
* @param pipe to read from
* @param loc location of data to read
* @return ASCII data
*/
public static Appendable readASCII(Pipe pipe, int loc, Appendable target) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
int len = PipeReader.readBytesLength(pipe,loc);
return Pipe.readASCII(pipe, target, pos, len);
}
/**
* Reads UTF8 from specified pipe
* @param pipe to read from
* @param loc location of data to read
* @return UTF8 data
*/
public static A readUTF8(Pipe pipe, int loc, A target) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
return (A)Pipe.readUTF8(pipe, target, pos, PipeReader.readBytesLength(pipe,loc));
}
/**
* Reads UTF8 in specified pipe and writes characters to char[]
* @param pipe to read
* @param loc location to read from
* @param target char array to write UTF8 to
* @return UTF8 data
*/
public static int readUTF8(Pipe pipe, int loc, char[] target, int targetOffset) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
int bytesLength = PipeReader.readBytesLength(pipe,loc);
if (pos < 0) {
return readUTF8Const(pipe,bytesLength,target, targetOffset, POS_CONST_MASK & pos);
} else {
return readUTF8Ring(pipe,bytesLength,target, targetOffset,Pipe.restorePosition(pipe, pos));
}
}
private static int readUTF8Const(Pipe pipe, int bytesLen, char[] target, int targetloc, int ringPos) {
long charAndPos = ((long)ringPos)<<32;
long limit = ((long)ringPos+bytesLen)<<32;
int i = targetloc;
while (charAndPos) pipe), charAndPos, pipe.blobMask);
target[i++] = (char)charAndPos;
}
return i - targetloc;
}
/**
* Reads ASCII characters in specific location of given pipe
* @param pipe to be read from
* @param loc location to read from
* @param target char[] to write ASCII data to
*/
public static int readASCII(Pipe pipe, int loc, char[] target, int targetOffset) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
long tmp = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp)];
int len = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp + 1)];
if (pos < 0) {
try {
readASCIIConst(pipe,len,target, targetOffset, POS_CONST_MASK & pos);
} catch (Exception e) {
e.printStackTrace();
System.err.println("pos now :"+(POS_CONST_MASK & pos)+" len "+len);
throw new RuntimeException(e);
}
} else {
readASCIIRing(pipe,len,target, targetOffset,Pipe.restorePosition(pipe, pos));
}
return len;
}
private static void readASCIIConst(Pipe pipe, int len, char[] target, int targetloc, int pos) {
byte[] buffer = pipe.blobConstBuffer;
while (--len >= 0) {
char c = (char)buffer[pos++];
target[targetloc++] = c;
}
}
private static void readASCIIRing(Pipe pipe, int len, char[] target, int targetloc, int pos) {
byte[] buffer = Pipe.blob(pipe);
int mask = pipe.blobMask;
while (--len >= 0) {
target[targetloc++]=(char)buffer[mask & pos++];
}
}
/**
* Checks to see if CharSequence matches UTF8 at given location
* @param pipe to be read from
* @param loc to read UTF8 from
* @param seq CharSequence to compare
* @return true
if they are equal else false
*/
public static boolean eqUTF8(Pipe pipe, int loc, CharSequence seq) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int len = PipeReader.readBytesLength(pipe,loc);
if (0==len && seq.length()==0) {
return true;
}
//char count is not comparable to byte count for UTF8 of length greater than zero.
//must convert one to the other before comparison.
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
if (pos < 0) {
return eqUTF8Const(pipe,len,seq,POS_CONST_MASK & pos);
} else {
return eqUTF8Ring(pipe,len,seq,Pipe.restorePosition(pipe,pos));
}
}
/**
* Checks to see if CharSequence matches ASCII at given location
* @param pipe to be read from
* @param loc to read ASCII from
* @param seq CharSequence to compare
* @return true
if they are equal else false
*/
public static boolean eqASCII(Pipe pipe, int loc, CharSequence seq) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
long idx = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
int len = Pipe.slab(pipe)[pipe.slabMask & (int)(idx + 1)];
if (len!=seq.length()) {
return false;
}
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)idx];
if (pos < 0) {
return eqASCIIConst(pipe,len,seq,POS_CONST_MASK & pos);
} else {
return eqASCIIRing(pipe,len,seq,Pipe.restorePosition(pipe,pos));
}
}
private static boolean eqASCIIConst(Pipe pipe, int len, CharSequence seq, int pos) {
byte[] buffer = pipe.blobConstBuffer;
int i = 0;
while (--len >= 0) {
if (seq.charAt(i++)!=buffer[pos++]) {
return false;
}
}
return true;
}
/**
* checks equals without moving buffer cursor.
*/
private static boolean eqUTF8Const(Pipe pipe, int bytesLen, CharSequence seq, int ringPos) {
long charAndPos = ((long)ringPos)<<32;
int i = 0;
int chars = seq.length();
while (--chars>=0) {
charAndPos = Pipe.decodeUTF8Fast(pipe.blobConstBuffer, charAndPos, Integer.MAX_VALUE);
if (seq.charAt(i++) != (char)charAndPos) {
return false;
}
}
return true;
}
private static boolean eqASCIIRing(Pipe pipe, int len, CharSequence seq, int pos) {
byte[] buffer = Pipe.blob(pipe);
int mask = pipe.blobMask;
int i = 0;
while (--len >= 0) {
if (seq.charAt(i++)!=buffer[mask & pos++]) {
//System.err.println("text match failure on:"+seq.charAt(i-1)+" pos "+pos+" mask "+mask);
return false;
}
}
return true;
}
private static boolean eqUTF8Ring(Pipe pipe, int lenInBytes, CharSequence seq, int ringPos) {
long charAndPos = ((long)ringPos)<<32;
long limit = ((long)ringPos+lenInBytes)<<32;
int mask = pipe.blobMask;
int i = 0;
int chars = seq.length();
while (--chars>=0 && charAndPos= 0 || charAndPos>STACK_OFF_SHIFT)] + (OFF_MASK&loc) + 1)];// second int is always the length
}
public static int readBytesMask(Pipe pipe, int loc) {
assert(0!=loc) : "This field needed for swapping to different array per field, like the constants array";
return pipe.blobMask;
}
/**
* Reads positions of bytes at specified location in given pipe
* @param pipe to read
* @param loc location to read from
* @return byte positions
*/
public static int readBytesPosition(Pipe pipe, int loc) {
int tmp = readBytesMeta(pipe, loc);
return tmp<0 ? POS_CONST_MASK & tmp : Pipe.restorePosition(pipe,tmp);// first int is always the length
}
/**
* Checks to see if pipe is structured at a certain location
* @param pipe to read
* @param loc location to check
* @return true
if pipe is structured
*/
public static boolean isStructured(Pipe pipe, int loc) {
return 0!=(Pipe.STRUCTURED_POS_MASK & readBytesMeta(pipe, loc));
}
private static int readBytesMeta(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc) )];
}
/**
* An access to internal data structures; advanced feature
* @return byteBackingArray for given pipe
*/
public static byte[] readBytesBackingArray(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc))];
if (pos>=0) {
return Pipe.blob((Pipe>) pipe);
} else {
new Exception("we are not fully done testing this feature").printStackTrace();
return pipe.blobConstBuffer;
}
}
public static ByteBuffer readBytes(Pipe pipe, int loc, ByteBuffer target) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
long tmp = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp)];
int len = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp + 1)];
return Pipe.readBytes(pipe, target, pos, len);
}
public static DataOutputBlobWriter> readBytes(Pipe pipe, int loc, DataOutputBlobWriter> target) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
long tmp = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
return Pipe.readBytes(pipe, target, Pipe.slab(pipe)[pipe.slabMask & (int)(tmp)], Pipe.slab(pipe)[pipe.slabMask & (int)(tmp + 1)]);
}
public static ByteBuffer[] wrappedUnstructuredLayoutBuffer(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
return wrappedUnstructuredLayoutBufferImpl(pipe, pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK & (loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc));
}
private static ByteBuffer[] wrappedUnstructuredLayoutBufferImpl(Pipe pipe, long pos) {
return wrappedUnstructuredLayoutBufferImpl(pipe,
Pipe.slab(pipe)[pipe.slabMask & (int)(pos)],
Pipe.slab(pipe)[pipe.slabMask & (int)(pos + 1)]);
}
private static ByteBuffer[] wrappedUnstructuredLayoutBufferImpl(Pipe pipe, int meta, int len) {
if (meta >= 0) {
ByteBuffer aBuf = Pipe.wrappedBlobRingA(pipe);
ByteBuffer bBuf = Pipe.wrappedBlobRingB(pipe);
return Pipe.positionedReadingBuffers(pipe, len, (pipe).blobMask & Pipe.convertToPosition(meta,pipe), aBuf, bBuf);
} else {
return Pipe.wrappedReadingBuffersConst(pipe, meta, len);
}
}
/**
* Reads byte array at specified location in pipe
* @param pipe pipe to check
* @param loc location to read from
* @param target target byte array
* @return length of byte array
*/
public static int readBytes(Pipe pipe, int loc, byte[] target, int targetOffset) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc)+" b"+Integer.toBinaryString(loc);
long tmp = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp)];
int len = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp + 1)];
if (pos < 0) {
readBytesConst(pipe,len,target,targetOffset,POS_CONST_MASK & pos);
} else {
readBytesRing(pipe,len,target,targetOffset,Pipe.restorePosition(pipe, pos));
}
return len;
}
private static void readBytesConst(Pipe pipe, int len, byte[] target, int targetloc, int pos) {
byte[] buffer = pipe.blobConstBuffer;
while (--len >= 0) {
target[targetloc++]=buffer[pos++]; //TODO:M replace with arrayCopy
}
}
private static void readBytesRing(Pipe pipe, int len, byte[] target, int targetloc, int pos) {
byte[] buffer = Pipe.blob(pipe);
int mask = pipe.blobMask;
while (--len >= 0) {
target[targetloc++]=buffer[mask & pos++]; //TODO:M replace with dual arrayCopy as seen elsewhere
}
}
/**
* Reads bytes in given pipe at specified location and populates target with bytes
* @param pipe pipe to read from
* @param loc location to read from
* @param target byte array to write to
* @return if len GTE 0 return len, else 0
*/
public static int readBytes(Pipe pipe, int loc, byte[] target, int targetOffset, int targetMask) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
long tmp = pipe.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(loc>>STACK_OFF_SHIFT)] + (OFF_MASK&loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp)];
int len = Pipe.slab(pipe)[pipe.slabMask & (int)(tmp + 1)];
if (len >= 0) {
if (len>0) {
if (pos < 0) {
readBytesConst(pipe,len,target, targetOffset,targetMask, POS_CONST_MASK & pos);
} else {
Pipe.copyBytesFromToRing(Pipe.blob(pipe), Pipe.restorePosition(pipe, pos), pipe.blobMask, target, targetOffset, targetMask, len);
}
}
return len;
} else {
return 0;
}
}
/**
* Copies int from specified pipe ring to target pipe ring
* @param sourceRing to copy from
* @param targetRing to copy to
* @param sourceLOC location of the int to copy
* @param targetLOC location to put the copied int
*/
public static void copyInt(final Pipe sourceRing, final Pipe targetRing, int sourceLOC, int targetLOC) {
assert(LOCUtil.isLocOfAnyType(sourceLOC, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional)): "Value found "+LOCUtil.typeAsString(sourceLOC);
assert(LOCUtil.isLocOfAnyType(targetLOC, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional)): "Value found "+LOCUtil.typeAsString(targetLOC);
Pipe.slab((Pipe>) targetRing)[targetRing.slabMask &((int)targetRing.ringWalker.activeWriteFragmentStack[PipeWriter.STACK_OFF_MASK&(targetLOC>>PipeWriter.STACK_OFF_SHIFT)] + (PipeWriter.OFF_MASK&targetLOC))] =
Pipe.slab((Pipe>) sourceRing)[sourceRing.slabMask & (int)(sourceRing.ringWalker.activeReadFragmentStack[STACK_OFF_MASK&(sourceLOC>>STACK_OFF_SHIFT)]+(OFF_MASK&sourceLOC))];
}
/**
* Copies long from specified pipe to target pipe
* @param sourcePipe to copy from
* @param targetPipe to copy to
* @param sourceLOC location of long to copy
* @param targetLOC location to put copied long
*/
public static void copyLong(final Pipe sourcePipe, final Pipe targetPipe, int sourceLOC, int targetLOC) {
assert((sourceLOC&0x1C<>PipeReader.OFF_BITS)&TokenBuilder.MASK_TYPE);
assert((targetLOC&0x1C<>PipeWriter.OFF_BITS)&TokenBuilder.MASK_TYPE);
long srcIdx = sourcePipe.ringWalker.activeReadFragmentStack[PipeReader.STACK_OFF_MASK&(sourceLOC>>PipeReader.STACK_OFF_SHIFT)] +(PipeReader.OFF_MASK&sourceLOC);
long targetIdx = (targetPipe.ringWalker.activeWriteFragmentStack[PipeWriter.STACK_OFF_MASK&(targetLOC>>PipeWriter.STACK_OFF_SHIFT)] + (PipeWriter.OFF_MASK&targetLOC));
Pipe.slab(targetPipe)[targetPipe.slabMask & (int)targetIdx] = Pipe.slab(sourcePipe)[sourcePipe.slabMask & (int)srcIdx];
Pipe.slab(targetPipe)[targetPipe.slabMask & (int)targetIdx+1] = Pipe.slab(sourcePipe)[sourcePipe.slabMask & (int)srcIdx+1];
}
/**
* Copies decimal from specified pipe ring to target pipe ring
* @param sourceRing to copy from
* @param targetRing to copy to
* @param sourceLOC location of decimal to copy
* @param targetLOC location to put copied decimal
*/
public static void copyDecimal(final Pipe sourceRing, final Pipe targetRing, int sourceLOC, int targetLOC) {
assert((sourceLOC&0x1E<>PipeReader.OFF_BITS)&TokenBuilder.MASK_TYPE);
assert((targetLOC&0x1E<>PipeWriter.OFF_BITS)&TokenBuilder.MASK_TYPE);
long srcIdx = sourceRing.ringWalker.activeReadFragmentStack[PipeReader.STACK_OFF_MASK&(sourceLOC>>PipeReader.STACK_OFF_SHIFT)] +(PipeReader.OFF_MASK&sourceLOC);
long targetIdx = (targetRing.ringWalker.activeWriteFragmentStack[PipeWriter.STACK_OFF_MASK&(targetLOC>>PipeWriter.STACK_OFF_SHIFT)] + (PipeWriter.OFF_MASK&targetLOC));
int[] tSlab = Pipe.slab(targetRing);
int[] sSlab = Pipe.slab(sourceRing);
tSlab[targetRing.slabMask & (int)targetIdx] = sSlab[sourceRing.slabMask & (int)srcIdx];
tSlab[targetRing.slabMask & (int)targetIdx+1] = sSlab[sourceRing.slabMask & (int)srcIdx+1];
tSlab[targetRing.slabMask & (int)targetIdx+2] = sSlab[sourceRing.slabMask & (int)srcIdx+2];
}
/**
* Copies bytes from specified pipe to target pipe
* @param sourcePipe to copy from
* @param targetPipe to copy to
* @param sourceLOC location of bytes to copy
* @param targetLOC location to put bytes
* @return length of copied bytes
*/
public static int copyBytes(final Pipe sourcePipe, final Pipe targetPipe, int sourceLOC, int targetLOC) {
assert(LOCUtil.isLocOfAnyType(sourceLOC, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(sourceLOC);
assert(LOCUtil.isLocOfAnyType(targetLOC, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(targetLOC);
//alternate implementation
DataInputBlobReader src = PipeReader.inputStream(sourcePipe, sourceLOC);
DataOutputBlobWriter tgt = PipeWriter.outputStream(targetPipe);
DataOutputBlobWriter.openField(tgt);
int len = src.available();
tgt.writeStream(src, len);
if (src.isStructured) {
src.readFromEndInto(tgt);
}
DataOutputBlobWriter.closeHighLevelField(tgt, targetLOC);
return len;
}
private static int copyBytes(final Pipe targetPipe, int targetLOC, int length) {
assert(LOCUtil.isLocOfAnyType(targetLOC, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(targetLOC);
int byteWrkHdPos = Pipe.getWorkingBlobHeadPosition(targetPipe);
Pipe.validateVarLength(targetPipe, length);
Pipe.setBytePosAndLen(Pipe.slab(targetPipe),
targetPipe.slabMask,
targetPipe.ringWalker.activeWriteFragmentStack[STACK_OFF_MASK&(targetLOC>>STACK_OFF_SHIFT)]+(OFF_MASK&targetLOC),
byteWrkHdPos, length, Pipe.bytesWriteBase(targetPipe));
Pipe.addAndGetBlobWorkingHeadPosition(targetPipe, length);
return length;
}
private static void readBytesConst(Pipe pipe, int len, byte[] target, int targetloc, int targetMask, int pos) {
byte[] buffer = pipe.blobConstBuffer;
while (--len >= 0) {//TODO:M replace with double arrayCopy as seen elsewhere
target[targetMask & targetloc++]=buffer[pos++];
}
}
/**
* Copies current message from input ring to output ring. Once copied that message is no longer readable.
* Message could be read before calling this copy using a low-level look ahead technique.
*
* Returns false until the full message is copied.
*
* Once called must continue to retry until true is returned or the message will be left in a partial state.
*
* NEVER follow this with publish since it has already been done.
*
* @param pipeIn
* @param pipeOut
*/
public static boolean tryMoveSingleMessage(Pipe pipeIn, Pipe pipeOut) {
assert( (!PipeReader.hasContentToRead(pipeIn))
|| (!PipeWriter.hasRoomForWrite(pipeOut))
|| PipeMonitor.monitor(pipeIn,
pipeIn.ringWalker.nextWorkingTail,
Pipe.bytesReadBase(pipeIn)
) );
assert(Pipe.from(pipeIn) == Pipe.from(pipeOut));
assert(Pipe.singleThreadPerPipeRead(pipeIn.id));
//NOTE: all the reading makes use of the high-level API to manage the fragment state, this call assumes tryRead was called once already.
//we may re-enter this function to continue the copy
boolean copied = StackStateWalker.copyFragment0(pipeIn, pipeOut, Pipe.getWorkingTailPosition(pipeIn), pipeIn.ringWalker.nextWorkingTail);
while (copied && !FieldReferenceOffsetManager.isTemplateStart(Pipe.from(pipeIn), pipeIn.ringWalker.nextCursor)) {
//using short circut logic so copy does not happen unless the prep is successful
copied = StackStateWalker.prepReadFragment(pipeIn, pipeIn.ringWalker) && StackStateWalker.copyFragment0(pipeIn, pipeOut, Pipe.getWorkingTailPosition(pipeIn), pipeIn.ringWalker.nextWorkingTail);
}
return copied;
}
/**
* Determines if rw is a new message
* @param rw StackStateWalker checked to see if it is a new message
* @return true
if rm is a new message, else false
*/
public static boolean isNewMessage(StackStateWalker rw) {
return rw.isNewMessage;
}
/**
* Determines if ring is a new message
* @param ring Pipe checked to see if it is a new message
* @return true
if ring is a new message, else false
*/
public static boolean isNewMessage(Pipe ring) {
return ring.ringWalker.isNewMessage;
}
/**
* Gets the message index in the pipe
* @param rb pipe to find index in
* @return message index
*/
public static int getMsgIdx(Pipe rb) {
return rb.lastMsgIdx = rb.ringWalker.msgIdx;
}
/**
* Gets the message index
* @param rw StackStateWalker to find index in
* @return message index
*/
static int getMsgIdx(StackStateWalker rw) {
return rw.msgIdx;
}
public static int bytesConsumedByFragment(Pipe ringBuffer) {
return ringBuffer.ringWalker.nextWorkingTail>0 ? bytesConsumed(ringBuffer) : 0;
}
/**
* Checks to see if pipe has content to read
* @param pipe to be checked
* @return true
if pipe has content, else false
*/
public static boolean hasContentToRead(Pipe pipe) {
return StackStateWalker.hasContentToRead(pipe);
}
/**
* @param pipe
* @param loc
* @param expected
* @return true if the value exists and matches the expected, when false is returned it does not mean not equals but rather undetermined.
*/
public static boolean peekEquals(Pipe pipe, int loc, int expected) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional, TypeMask.GroupLength)): "Value found "+LOCUtil.typeAsString(loc);
return StackStateWalker.hasContentToRead(pipe) && (expected == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc)));
}
/**
* Checks pipe to see if message equals expected
* @param pipe to be checked
* @param expected used for comparison with message
* @return true
if message == expected, else false
*/
public static boolean peekMsg(Pipe pipe, int expected) {
assert(Pipe.singleThreadPerPipeRead(pipe.id));
return StackStateWalker.hasContentToRead(pipe)
&& (expected == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail));
}
/**
* Checks pipe to see if message equals expected
* @param pipe to be checked
* @param expected1 used for comparison with message
* @param expected2 used for comparison with message
* @return true
if message == expected1 and expected2, else false
*/
public static boolean peekMsg(Pipe pipe, int expected1, int expected2) {
assert(Pipe.singleThreadPerPipeRead(pipe.id));
return StackStateWalker.hasContentToRead(pipe)
&& (
(expected1 == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail))
|| (expected2 == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail))
);
}
/**
* Checks pipe to see if message equals expected
* @param pipe to be checked
* @param expected1 used for comparison with message
* @param expected2 used for comparison with message
* @param expected3 used for comparison with message
* @return true
if message equals expected1, expected2 and expected3, else false
*/
public static boolean peekMsg(Pipe pipe, int expected1, int expected2, int expected3) {
assert(Pipe.singleThreadPerPipeRead(pipe.id));
return StackStateWalker.hasContentToRead(pipe)
&& (
(expected1 == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail))
|| (expected2 == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail))
|| (expected3 == Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail))
);
}
/**
* Checks pipe to see if message does not equal expected
* @param pipe to be checked
* @param expected used for comparison
* @return true
if message != expected, else false
*/
public static boolean peekNotMsg(Pipe pipe, int expected) {
return StackStateWalker.hasContentToRead(pipe) && (expected != Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail));
}
/**
* Checks pipe to see if message does not equal expected
* @param pipe to be checked
* @param expected1 used for comparison
* @param expected2 used for comparison
* @return true
if message != expected1 and message != expected2, else false
*/
public static boolean peekNotMsg(Pipe pipe, int expected1, int expected2) {
return StackStateWalker.hasContentToRead(pipe) &&
(expected1 != Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail)) &&
(expected2 != Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail));
}
/**
* Peeks ahead to specified field in pipe before Trie parsing is done
* @param pipe pipe to read
* @param loc field to peek in
* @return int data in that field
*/
public static int peekInt(Pipe pipe, int loc) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.IntegerSigned, TypeMask.IntegerSignedOptional, TypeMask.IntegerUnsigned, TypeMask.IntegerUnsignedOptional, TypeMask.GroupLength)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.readValue(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc));
}
/**
* Peeks ahead to specified field in pipe before Trie parsing is run
* @param pipe pipe to read
* @param loc field to peek in
* @return long data in that field
*/
public static long peekLong(Pipe pipe, int loc) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.LongSigned, TypeMask.LongSignedOptional, TypeMask.LongUnsigned, TypeMask.LongUnsignedOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.readLong(Pipe.slab(pipe),pipe.slabMask,pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc));
}
/**
* Peeks ahead to specified field in pipe before Trie parsing is run
* @param pipe pipe to read
* @param loc field to peek in
* @return UTF8 data in that field
*/
public static A peekUTF8(Pipe pipe, int loc, A target) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
return (A)Pipe.readUTF8(pipe, target, peekDataPosition(pipe, loc), PipeReader.peekDataLength(pipe, loc));
}
/**
* Peeks ahead to specified field in pipe before Trie parsing is run
* @param pipe pipe to read
* @param loc field to peek in
* @return length of data in that field
*/
public static int peekDataLength(Pipe pipe, int loc) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc)+1)];// second int is always the length
}
public static int peekDataPosition(Pipe pipe, int loc) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int meta = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc))];
return meta<0 ? POS_CONST_MASK & meta : Pipe.restorePosition(pipe, meta);
}
public static int peekDataMeta(Pipe pipe, int loc) {
assert(PipeReader.hasContentToRead(pipe)) : "results would not be repeatable, before peek hasContentToRead must be called.";
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
return Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.nextWorkingTail+(OFF_MASK&loc))];
}
/**
* Peeks at internal data; advanced feature
*/
public static byte[] peekDataBackingArray(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc);
int pos = Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.nextWorkingTail+ (OFF_MASK&loc))];
if (pos>=0) {
return Pipe.blob(pipe);
} else {
new Exception("we are not fully done testing this feature").printStackTrace();
return pipe.blobConstBuffer;
}
}
/**
* Peeks at input stream of specified pipe before Trie parse is run
* @param pipe pipe to read
* @return stream
*/
public static > DataInputBlobReader peekInputStream(Pipe pipe, int loc) {
assert(LOCUtil.isLocOfAnyType(loc, TypeMask.TextASCII, TypeMask.TextASCIIOptional, TypeMask.TextUTF8, TypeMask.TextUTF8Optional, TypeMask.ByteVector, TypeMask.ByteVectorOptional)): "Value found "+LOCUtil.typeAsString(loc)+" b"+Integer.toBinaryString(loc);
DataInputBlobReader stream = Pipe.inputStream(pipe);
DataInputBlobReader.peekHighLevelAPIField(stream, loc);
return stream;
}
//this impl only works for simple case where every message is one fragment.
public static > boolean tryReadFragment(Pipe pipe) {
assert( (!PipeReader.hasContentToRead(pipe)) || PipeMonitor.monitor(pipe,
pipe.ringWalker.nextWorkingTail,
Pipe.bytesReadBase(pipe)
) );
assert(pipe.usingHighLevelAPI);
assert(Pipe.singleThreadPerPipeRead(pipe.id));
assert(null!=pipe.ringWalker) : "NullPointer, double check that pipe was passed into super constructor of stage.";
if (FieldReferenceOffsetManager.isTemplateStart(Pipe.from(pipe), pipe.ringWalker.nextCursor)) {
assert(StackStateWalker.isSeqStackEmpty(pipe.ringWalker)) : "Error the seqStack should be empty";
return StackStateWalker.prepReadMessage(pipe, pipe.ringWalker);
} else {
return StackStateWalker.prepReadFragment(pipe, pipe.ringWalker);
}
}
private static int collectConsumedCountOfBytes(Pipe pipe) {
if (pipe.ringWalker.nextWorkingTail>0) { //first iteration it will not have a valid position
//must grab this value now, its the last chance before we allow it to be written over.
//these are all accumulated from every fragment, messages many have many fragments.
int bytesConsumed = bytesConsumed(pipe);
Pipe.addAndGetBlobWorkingTailPosition(pipe, bytesConsumed);
return bytesConsumed;
}
return 0;
}
private static int bytesConsumed(Pipe pipe) {
return Pipe.slab(pipe)[pipe.slabMask & (int)(pipe.ringWalker.nextWorkingTail-1)];
}
/**
* Release the record which has been most recently read.
* The act of releasing a record/message allows it to now be written over.
* @param pipe The pipe where this message is found.
* @return The total number of variable length field bytes consumed by this now released message.
*/
public static int releaseReadLock(Pipe pipe) {
assert(Pipe.singleThreadPerPipeRead(pipe.id));
int consumed = collectConsumedCountOfBytes(pipe);
//ensure we only call for new templates.
if (FieldReferenceOffsetManager.isTemplateStart(Pipe.from(pipe), pipe.ringWalker.nextCursor)) {
assert(Pipe.isReplaying(pipe) || pipe.ringWalker.nextWorkingTail!=Pipe.getWorkingTailPosition(pipe)) : "Only call release once per message";
Pipe.markBytesReadBase(pipe); //moves us forward so we can read the next fragment/message
Pipe.releaseBatchedReads(pipe, Pipe.getWorkingBlobTailPosition(pipe), pipe.ringWalker.nextWorkingTail);
} else {
Pipe.decBatchRelease(pipe);//sequence fragments must cause this number to move
}
//ensure that the working value does not fall behind the new published tail position.
//this allows peek by direct offset to be supported when needed
Pipe.setWorkingTailPosition(pipe, Pipe.tailPosition(pipe));
return consumed;
}
/**
* Release all pending records
* @param pipe the pipe where this message is found
*/
public static void releaseAllPendingReadLock(Pipe pipe) {
Pipe.releaseAllPendingReadLock(pipe);
}
public static void releaseAllPendingReadLock(Pipe pipe, int consumed) {
Pipe.releasePendingAsReadLock(pipe, consumed);
}
/**
* Reads next message without allowing ReadLock to be overwritten
* @param pipe pipe where this message is found
*/
public static boolean readNextWithoutReleasingReadLock(Pipe pipe) {
assert(Pipe.singleThreadPerPipeRead(pipe.id));
int bytesConsumed = collectConsumedCountOfBytes(pipe);
if (FieldReferenceOffsetManager.isTemplateStart(Pipe.from(pipe), pipe.ringWalker.nextCursor)) {
assert(Pipe.isReplaying(pipe) || pipe.ringWalker.nextWorkingTail!=Pipe.getWorkingTailPosition(pipe)) : "Only call release once per message";
//moves us forward so we can read the next fragment/message
Pipe.markBytesReadBase(pipe);
PendingReleaseData.appendPendingReadRelease(pipe.pendingReleases,
pipe.ringWalker.nextWorkingTail,
Pipe.getWorkingBlobTailPosition(pipe),
bytesConsumed);
return true;
} else {
return false;
}
}
/**
* Gives the size of the fragment from input to the end of pipe
* @param input starting point from which to measure fragment
* @return size of fragment
*/
public static int sizeOfFragment(Pipe input) {
return Pipe.from(input).fragDataSize[input.ringWalker.cursor];
}
/**
* Prints fragment from input to the end of pipe
* @param input starting point from which to print fragment
* @param target where to print fragment
*/
public static void printFragment(Pipe input, Appendable target) {
int cursor = input.ringWalker.cursor;
try {
if (cursor<0) {
target.append("EOF").append("/n");
return;
}
target.append(" new message: "+input.ringWalker.isNewMessage);
} catch (IOException ioe) {
log.error("Unable to build text for fragment.",ioe);
throw new RuntimeException(ioe);
}
Pipe.appendFragment(input, target, cursor);
}
/**
* Reads specified field in given pipe into the OutputStream
* @param loc field to read to stream
* @param pipe to be read from
* @param out stream to read into
*/
public static void readFieldIntoOutputStream(int loc, Pipe pipe, OutputStream out) throws IOException {
int length = readBytesLength(pipe, loc);
if (length>0) {
int off = readBytesPosition(pipe, loc) & Pipe.blobMask(pipe);
copyFieldToOutputStream(out, length, readBytesBackingArray(pipe, loc), off, pipe.sizeOfBlobRing-off);
}
}
public static void readFieldIntoDataOutput(int loc, Pipe pipe, DataOutput out) throws IOException {
int length = readBytesLength(pipe, loc);
if (length>0) {
int off = readBytesPosition(pipe, loc) & Pipe.blobMask(pipe);
copyFieldToDataOutput(out, length, readBytesBackingArray(pipe, loc), off, pipe.sizeOfBlobRing-off);
}
}
private static void copyFieldToOutputStream(OutputStream out, int length, byte[] backing, int off, int len1)
throws IOException {
if (len1>=length) {
//simple add bytes
out.write(backing, off, length);
} else {
//rolled over the end of the buffer
out.write(backing, off, len1);
out.write(backing, 0, length-len1);
}
}
private static void copyFieldToDataOutput(DataOutput out, int length, byte[] backing, int off, int len1)
throws IOException {
if (len1>=length) {
//simple add bytes
out.write(backing, off, length);
} else {
//rolled over the end of the buffer
out.write(backing, off, len1);
out.write(backing, 0, length-len1);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy