com.javanut.pronghorn.pipe.stream.AppendableUTF8Ring 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.tailPosition;
import java.io.IOException;
import com.javanut.pronghorn.pipe.Pipe;
import com.javanut.pronghorn.pipe.RawDataSchema;
public class AppendableUTF8Ring implements Appendable {
private final Pipe ringBuffer;
private final char[] temp = new char[1];
private long outputTarget;
private long tailPosCache;
private final static int step = RawDataSchema.FROM.fragDataSize[0];
public AppendableUTF8Ring(Pipe ringBuffer) {
this.ringBuffer = ringBuffer;
if (Pipe.from(ringBuffer) != RawDataSchema.FROM) {
throw new UnsupportedOperationException("This class can only be used with the very simple RAW_BYTES catalog of messages.");
}
int messagesPerRing = (1<<(ringBuffer.bitsOfSlabRing-1));
outputTarget = step-messagesPerRing;//this value is negative
tailPosCache = tailPosition(ringBuffer);
}
@Override
public Appendable append(CharSequence csq) throws IOException {
long lastCheckedValue = tailPosCache;
while (null==Pipe.slab(ringBuffer) || lastCheckedValue < outputTarget) {
Pipe.spinWork(ringBuffer);
lastCheckedValue = Pipe.tailPosition(ringBuffer);
}
tailPosCache = lastCheckedValue;
outputTarget+=step;
Pipe.addMsgIdx(ringBuffer, 0);
Pipe.validateVarLength(ringBuffer, csq.length()<<3);//UTF8 encoded bytes are longer than the char count (6 is the max but math for 8 is cheaper)
Pipe.addBytePosAndLen(ringBuffer, Pipe.getWorkingBlobHeadPosition((Pipe>) ringBuffer), Pipe.copyUTF8ToByte(csq,0, csq.length(), ringBuffer));
Pipe.publishWrites(ringBuffer);
return this;
}
@Override
public Appendable append(CharSequence csq, int start, int end)
throws IOException {
long lastCheckedValue = tailPosCache;
while (null==Pipe.slab(ringBuffer) || lastCheckedValue < outputTarget) {
Pipe.spinWork(ringBuffer);
lastCheckedValue = Pipe.tailPosition(ringBuffer);
}
tailPosCache = lastCheckedValue;
outputTarget+=step;
Pipe.addMsgIdx(ringBuffer, 0);
Pipe.validateVarLength(ringBuffer, csq.length()<<3);//UTF8 encoded bytes are longer than the char count (6 is the max but math for 8 is cheaper)
Pipe.addBytePosAndLen(ringBuffer, Pipe.getWorkingBlobHeadPosition((Pipe>) ringBuffer), Pipe.copyUTF8ToByte(csq,0, end-start, ringBuffer));
Pipe.publishWrites(ringBuffer);
return this;
}
@Override
public Appendable append(char c) throws IOException {
long lastCheckedValue = tailPosCache;
while (null==Pipe.slab(ringBuffer) || lastCheckedValue < outputTarget) {
Pipe.spinWork(ringBuffer);
lastCheckedValue = Pipe.tailPosition(ringBuffer);
}
tailPosCache = lastCheckedValue;
outputTarget+=step;
temp[0]=c; //TODO: C, This should be optimized however callers should prefer to use the other two methods.
Pipe.addMsgIdx(ringBuffer, 0);
Pipe.validateVarLength(ringBuffer, temp.length<<3);
//UTF8 encoded bytes are longer than the char count (6 is the max but math for 8 is cheaper)
Pipe.addBytePosAndLen(ringBuffer, Pipe.getWorkingBlobHeadPosition((Pipe>) ringBuffer), Pipe.copyUTF8ToByte(temp, temp.length, ringBuffer));
Pipe.publishWrites(ringBuffer);
return this;
}
public void flush() {
long lastCheckedValue = tailPosCache;
while (null==Pipe.slab(ringBuffer) || lastCheckedValue < outputTarget) {
Pipe.spinWork(ringBuffer);
lastCheckedValue = Pipe.tailPosition(ringBuffer);
}
tailPosCache = lastCheckedValue;
outputTarget+=2;
RingStreams.writeEOF(ringBuffer);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy