if vBeginning >= fBufferSize then // deletion range outside the buffer. Exit; if (vBeginning >= fGapStart) and (vBeginning < fGapEnd) then begin { deletions inside the gap are weird, so skip the gap. } assert(vBeginning = fGapStart); // postcondition of #PositionFromTextMark {Inc(vBeginning, fGapEnd - fGapStart);} vBeginning := fGapEnd; end; if (vEnd >= fGapStart) and (vEnd < fGapEnd) then begin { don't shrink the gap. } vEnd := fGapStart; end; assert((vBeginning < fGapStart) or (vBeginning >= fGapEnd)); if vBeginning >= vEnd then // deletion range empty. Exit; vMovingBlockSize := fBufferSize - vEnd; vGapAffectedP := (vBeginning < fGapStart){ must be and (vEnd >= fGapStart)}; // and (vBeginning < fGapEnd and vEnd >= fGapStart), that being the more obvious condition. // the gap can only be used when vEnd [>]= fGapStart or vBeginning [<]= fGapEnd, otherwise we need to move it which is associated with a cost proportional to the relative movement of the gap. // abcGGGGdef // ^ ^ // B E // abcGGGGdef // ^ ^ // B E vIntersectionStart := Max(vBeginning, fGapStart); vIntersectionEnd1 := Min(vEnd, fGapEnd); vOffset := vBeginning - vEnd; if vIntersectionStart < vIntersectionEnd1 then begin // there is an intersection assert(vGapAffectedP); end else begin // there is no intersection with the gap vIntersectionStart := vEnd; vIntersectionEnd1 := vEnd; assert(not vGapAffectedP); end; { optimized path: when the deletion range is adjacent to the gap. } if vIntersectionStart = fGapStart { TODO and some gap size limit is not exceeded } then begin fGapStart := vBeginning; FillChar(fBuffer[fGapStart], vIntersectionStart - fGapStart, 0); { for better debugging. } vIntersectionStart := fGapStart; end; if vIntersectionEnd1 = fGapEnd { TODO and some gap size limit is not exceeded } then begin fGapEnd := vEnd; FillChar(fBuffer[vIntersectionEnd1], fGapEnd - vIntersectionEnd1, 0); { for better debugging. } vIntersectionEnd1 := fGapEnd; end; { normal path. } { destination: [ vBeginning : vIntersectionStart [ is the first range to be deleted, if any. [ vIntersectionEnd1 : vEnd [ is the second range to be deleted, if any. both do not intersect the gap. } { vOffset is how much data needs to be moved. In case the fast paths did half of the work, update it. } vOffset := (vIntersectionStart - vBeginning) + (vEnd - vIntersectionEnd1); // source of the new data is the first chunk that is NOT in the deletion range, i.e. [ fEnd : fBufferSize [ X not [ fGapStart, fGapEnd [