in packages/core/micro/src/permutation/index.ts [79:151]
function extractSegmentRange(segment: PermutationSegment, start: number, length: number) {
switch (segment.kind) {
case PermutationKind.Empty:
return emptyPair;
case PermutationKind.Direct:
return {
retained: segment,
removed: { kind: PermutationKind.Direct, content: segment.content.splice(start, length) },
};
case PermutationKind.RunLength:
const content = segment.content;
const size = content.length;
let startIndex = 0;
let startPos = start;
while (startIndex < size) {
const len = content[startIndex];
if (startPos < len) {
break;
}
startPos -= len;
startIndex += 2;
}
let endIndex = 0;
let endPos = start + length;
while (endIndex < size) {
const len = content[endIndex];
if (endPos < len) {
break;
}
endPos -= len;
endIndex += 2;
}
if (startIndex === endIndex) {
const len = content[startIndex];
const base = content[startIndex + 1];
const result = {
retained: segment,
removed: { kind: PermutationKind.RunLength, content: [len, base + startPos] }
};
if (startPos === 0) {
content[startIndex] = len - endPos;
content[startIndex + 1] = base + endPos;
return result;
}
if (endPos > 0) {
content.splice(startIndex, 2, startPos, base, len - endPos, base + endPos);
} else {
content[startIndex] = startPos;
}
return result
}
const wholeStartIndex = startPos === 0 ? startIndex : startIndex + 2;
const toRemove = endIndex - wholeStartIndex;
endIndex -= toRemove;
const removed: number[] = toRemove > 0 ? content.splice(wholeStartIndex, toRemove) : [];
if (startPos > 0) {
removed.unshift(content[startIndex] - startPos, content[startIndex + 1] + startPos);
content[startIndex] = startPos;
}
if (endPos > 0) {
removed[removed.length] = endPos;
removed[removed.length] = content[endIndex + 1] - endPos;
content[endIndex] -= endPos;
}
return { retained: segment, removed: { kind: PermutationKind.RunLength, content: removed } };
}
}