com.javanut.pronghorn.pipe.PendingReleaseData 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;
public class PendingReleaseData {
private final int pendingReleaseSize;
private final int pendingReleaseMask;
private int pendingReleaseHead;
private int pendingReleaseTail;
private int pendingReleaseCount;
private final int[] pendingBlobReleaseRing;
private final long[] pendingSlabReleaseRing;
private final int[] pendingLength;
public PendingReleaseData(int maxFragsInPipe) {
pendingReleaseSize = 1 << (int)Math.ceil(Math.log(maxFragsInPipe)/Math.log(2));
pendingReleaseMask = pendingReleaseSize-1;
pendingBlobReleaseRing = new int[pendingReleaseSize];
pendingSlabReleaseRing = new long[pendingReleaseSize];
pendingLength = new int[pendingReleaseSize];
}
public static void appendPendingReadRelease(PendingReleaseData that, long slabTail, int blobTail, int fragBytesLen) {
int idx = that.pendingReleaseMask & that.pendingReleaseHead++;
assert(that.pendingReleaseHead-that.pendingReleaseTail<=that.pendingLength.length);
that.pendingBlobReleaseRing[idx] = blobTail;
that.pendingSlabReleaseRing[idx] = slabTail;
that.pendingLength[idx] = fragBytesLen;
that.pendingReleaseCount++;
assert(that.pendingReleaseCount<=that.pendingLength.length);
}
public static > int pendingReleaseCount(PendingReleaseData that) {
return that.pendingReleaseCount;
}
public static > int pendingReleaseByteCount(PendingReleaseData that) {
int total = 0;
int t = that.pendingReleaseTail;
int c = that.pendingReleaseCount;
while (--c>=0) {
int idx = that.pendingReleaseMask & t;
total += that.pendingLength[idx];
t++;
}
return total;
}
public static > void releasePendingReadRelease(PendingReleaseData that, Pipe pipe) {
if (that.pendingReleaseCount>0) {
int idx = that.pendingReleaseMask & that.pendingReleaseTail++;
Pipe.releaseBatchedReads(pipe,
that.pendingBlobReleaseRing[idx],
that.pendingSlabReleaseRing[idx]);
that.pendingReleaseCount--;
}
}
public static > void releaseAllPendingReadRelease(PendingReleaseData that, Pipe pipe) {
if (pipe.batchReleaseCountDownInit<=0) {
nonBatchedReleaseAll(that, pipe);
} else {
batchedReleaseAll(that, pipe);
}
}
private static > void batchedReleaseAll(PendingReleaseData that, Pipe pipe) {
while (that.pendingReleaseCount>0) {
int idx = that.pendingReleaseMask & that.pendingReleaseTail++;
Pipe.releaseBatchedReads(pipe,
that.pendingBlobReleaseRing[idx],
that.pendingSlabReleaseRing[idx]);
that.pendingReleaseCount--;
}
}
private static > void nonBatchedReleaseAll(PendingReleaseData that, Pipe pipe) {
//simple case when we do not batch.
int c = that.pendingReleaseCount;
if (c>0) {
that.pendingReleaseTail+=c;
int idx = that.pendingReleaseMask & (that.pendingReleaseTail-1);
int newTail = that.pendingBlobReleaseRing[idx];
Pipe.setBlobTailPosition(pipe,newTail);
pipe.slabRingTail.tailPos.lazySet(that.pendingSlabReleaseRing[idx]);
that.pendingReleaseCount = 0;
}
}
//releases as the bytes are consumed, this can be called as many times as needed.
public static > void releasePendingAsReadRelease(PendingReleaseData that, Pipe pipe, int consumed) {
assert(consumed<=Pipe.releasePendingByteCount(pipe)) : "requested more to released than we have pending releasing "+consumed+" but found "+Pipe.releasePendingByteCount(pipe);
int rc = that.pendingReleaseCount;
if (rc > 0) {
int idx=0;
final int mask = that.pendingReleaseMask;
final int[] pendingLength2 = that.pendingLength;
int rt = that.pendingReleaseTail;
while (rc>0 && (consumed>0 || pendingLength2[mask & rt]<=0) ) {
idx = mask & rt;
int tmp = pendingLength2[idx];
if (tmp>consumed) {
pendingLength2[idx] = tmp-consumed;
that.pendingReleaseCount=rc;
that.pendingReleaseTail=rt;
return;
}
if (tmp>0) {
consumed -= tmp;
}
pendingLength2[idx]=0;
Pipe.releaseBatchedReads(pipe,
that.pendingBlobReleaseRing[idx],
that.pendingSlabReleaseRing[idx]);
rc--;
rt++;
}
assert(0==consumed || 0!=rc) : "remaining bytes "+consumed+" but pending fragments "+rc;
that.pendingReleaseCount=rc;
that.pendingReleaseTail=rt;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy