in accord-core/src/main/java/accord/local/RedundantBefore.java [219:328]
private static Bounds merge(Range range, Bounds cur, Bounds add)
{
// TODO (required): we shouldn't be trying to merge non-intersecting epochs
if (cur.startEpoch > add.endEpoch)
return cur;
if (add.startEpoch > cur.endEpoch)
return add;
int csu = compareStaleUntilAtLeast(cur.staleUntilAtLeast, add.staleUntilAtLeast);
Timestamp staleUntilAtLeast = csu >= 0 ? cur.staleUntilAtLeast : add.staleUntilAtLeast;
staleUntilAtLeast = maybeClearStaleUntilAtLeast(staleUntilAtLeast, cur.bounds, cur.statuses);
staleUntilAtLeast = maybeClearStaleUntilAtLeast(staleUntilAtLeast, add.bounds, add.statuses);
long startEpoch = Long.max(cur.startEpoch, add.startEpoch);
long endEpoch = Long.min(cur.endEpoch, add.endEpoch);
TxnId[] mergedBounds;
short[] mergedStatuses;
{
Object[] boundBuf = null;
short[] statusBuf = null;
int mergedCount = 0;
short prevLtStatus = staleUntilAtLeast == null ? 0 : PRE_BOOTSTRAP_OR_STALE_ONLY.encodedPart(SOME);
short prevExistingLtStatus = prevLtStatus; // we don't apply PRE_BOOTSTRAP_MERGE_MASK as this already applied
int i = 0, j = 0;
while (i < cur.bounds.length || j < add.bounds.length)
{
int c = i == cur.bounds.length ? -1 : j == add.bounds.length ? 1 : cur.bounds[i].compareTo(add.bounds[j]);
TxnId nextBound;
short leStatus, ltStatus;
if (c > 0)
{
nextBound = cur.bounds[i];
leStatus = addHistory(prevLtStatus, cur.statuses[i*2]);
ltStatus = addHistory(prevLtStatus, prevExistingLtStatus = cur.statuses[i*2+1]);
++i;
}
else if (c < 0)
{
nextBound = add.bounds[j];
leStatus = addHistory((short) (prevLtStatus | add.statuses[j * 2]), prevExistingLtStatus);
ltStatus = addHistory((short) (prevLtStatus | add.statuses[j * 2 + 1]), prevExistingLtStatus);
++j;
}
else
{
nextBound = cur.bounds[i].addFlags(add.bounds[j]);
leStatus = addHistory((short) (prevLtStatus | add.statuses[j * 2]), cur.statuses[i * 2]);
ltStatus = addHistory((short) (prevLtStatus | add.statuses[j * 2 + 1]), prevExistingLtStatus = cur.statuses[i * 2 + 1]);
++i;
++j;
}
// we keep the start/end bound of an equal pre-bootstrap run, so that we correctly apply Property.mergeWithPreBootstrap
if (leStatus == ltStatus && ltStatus == prevLtStatus)
{
if (!any(prevLtStatus, PRE_BOOTSTRAP_OR_STALE))
continue;
if (mergedCount >= 2)
{
short[] prev = statusBuf != null ? statusBuf : cur.statuses;
short prev2LtStatus = prev[mergedCount*2 - 3];
short prevLeStatus = prev[mergedCount*2 - 2];
Invariants.require(prevLtStatus == prev[mergedCount*2 - 1]);
if (prevLtStatus == prev2LtStatus && prevLeStatus == prev2LtStatus)
--mergedCount;
}
}
if (boundBuf == null)
{
if (mergedCount < cur.bounds.length && cur.bounds[mergedCount].equalsStrict(nextBound)
&& cur.statuses[mergedCount*2] == leStatus && cur.statuses[mergedCount*2+1] == ltStatus)
{
prevLtStatus = ltStatus;
++mergedCount;
continue;
}
boundBuf = cachedAny().get(cur.bounds.length + add.bounds.length);
statusBuf = cachedShorts().getShorts((cur.bounds.length + add.bounds.length) * 2);
System.arraycopy(cur.bounds, 0, boundBuf, 0, mergedCount);
System.arraycopy(cur.statuses, 0, statusBuf, 0, mergedCount*2);
}
boundBuf[mergedCount] = nextBound;
statusBuf[mergedCount*2] = leStatus;
statusBuf[mergedCount*2 + 1] = ltStatus;
++mergedCount;
prevLtStatus = ltStatus;
}
if (boundBuf == null)
{
mergedBounds = mergedCount == cur.bounds.length ? cur.bounds : Arrays.copyOf(cur.bounds, mergedCount);
mergedStatuses = mergedCount == cur.statuses.length ? cur.statuses : Arrays.copyOf(cur.statuses, mergedCount * 2);
}
else
{
mergedBounds = new TxnId[mergedCount];
mergedStatuses = new short[mergedCount*2];
System.arraycopy(boundBuf, 0, mergedBounds, 0, mergedCount);
System.arraycopy(statusBuf, 0, mergedStatuses, 0, mergedCount*2);
cachedAny().forceDiscard(boundBuf, mergedCount);
cachedShorts().forceDiscard(statusBuf);
}
}
return new Bounds(range, startEpoch, endEpoch, mergedBounds, mergedStatuses, staleUntilAtLeast);
}