mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-01 13:00:25 +02:00
SynEdit: Refactor AVL
git-svn-id: trunk@40174 -
This commit is contained in:
parent
4bfedf1d24
commit
c13054e9c5
@ -201,6 +201,7 @@ type
|
||||
protected
|
||||
// will be reset by TSynEditMarkLine.ChangeSize;
|
||||
FLastIteratorIndex: Integer;
|
||||
function CreateNode(APosition: Integer): TSynSizedDifferentialAVLNode; override;
|
||||
public
|
||||
constructor Create(AOwner: TSynEditMarkList);
|
||||
destructor Destroy; override;
|
||||
@ -717,26 +718,11 @@ begin
|
||||
end;
|
||||
|
||||
function TSynEditMarkLineList.GetMarkLineByMarkIndex(var AMarkIndex: Integer): TSynEditMarkLine;
|
||||
var
|
||||
d1, d2: Integer;
|
||||
begin
|
||||
Result := TSynEditMarkLine(FRoot);
|
||||
while Result <> nil do begin
|
||||
|
||||
if AMarkIndex < Result.LeftSizeSum then begin
|
||||
Result := Result.Left;
|
||||
continue;
|
||||
end;
|
||||
|
||||
AMarkIndex := AMarkIndex - Result.LeftSizeSum;
|
||||
if AMarkIndex < Result.Size then begin
|
||||
break;
|
||||
end
|
||||
else begin
|
||||
AMarkIndex := AMarkIndex - Result.Size;
|
||||
Result := Result.Right;
|
||||
continue;
|
||||
end;
|
||||
|
||||
end;
|
||||
Result := TSynEditMarkLine(FindNodeAtLeftSize(AMarkIndex, d1, d2));
|
||||
AMarkIndex := AMarkIndex - d2;
|
||||
end;
|
||||
|
||||
function TSynEditMarkLineList.GetMarkLine(LineNum: Integer): TSynEditMarkLine;
|
||||
@ -749,50 +735,15 @@ function TSynEditMarkLineList.GetOrAddMarkLine(LineNum: Integer;
|
||||
var
|
||||
rStartPosition: Integer;
|
||||
p: TSynEditMarkLine;
|
||||
d1, d2: Integer;
|
||||
begin
|
||||
Result := TSynEditMarkLine(FRoot);
|
||||
if (Result = nil) and AddIfNotExist then begin
|
||||
Result := TSynEditMarkLine.Create(LineNum, Self);
|
||||
SetRoot(Result);
|
||||
exit;
|
||||
end;
|
||||
|
||||
rStartPosition := fRootOffset;
|
||||
p := nil;
|
||||
|
||||
while (Result <> nil) do begin
|
||||
rStartPosition := rStartPosition + Result.FPositionOffset;
|
||||
|
||||
if rStartPosition > LineNum then begin
|
||||
if (Result.Left = nil) and AddIfNotExist then begin
|
||||
p := Result;
|
||||
Result := TSynEditMarkLine.Create(LineNum, Self);
|
||||
p.SetLeftChild(Result, -rStartPosition);
|
||||
BalanceAfterInsert(Result);
|
||||
break;
|
||||
end;
|
||||
// Store current in p, as posible UseNext
|
||||
p := Result;
|
||||
Result := Result.Left;
|
||||
end
|
||||
|
||||
else if LineNum = rStartPosition then begin
|
||||
break;
|
||||
end
|
||||
|
||||
else if rStartPosition < LineNum then begin
|
||||
if (Result.Right = nil) and AddIfNotExist then begin
|
||||
p := Result;
|
||||
Result := TSynEditMarkLine.Create(LineNum, Self);
|
||||
p.SetRightChild(Result, -rStartPosition);
|
||||
BalanceAfterInsert(Result);
|
||||
break;
|
||||
end;
|
||||
Result := Result.Right;
|
||||
end;
|
||||
end; // while
|
||||
if UseNext and (Result = nil) then
|
||||
Result := p;
|
||||
if AddIfNotExist then
|
||||
Result := TSynEditMarkLine(FindNodeAtPosition(LineNum, afmCreate, d1, d2))
|
||||
else
|
||||
if UseNext then
|
||||
Result := TSynEditMarkLine(FindNodeAtPosition(LineNum, afmNext, d1, d2))
|
||||
else
|
||||
Result := TSynEditMarkLine(FindNodeAtPosition(LineNum, afmNil, d1, d2));
|
||||
end;
|
||||
|
||||
procedure TSynEditMarkLineList.AdjustForLinesInserted(AStartLine, ALineCount: Integer);
|
||||
@ -856,6 +807,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynEditMarkLineList.CreateNode(APosition: Integer): TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := TSynEditMarkLine.Create(APosition, Self);
|
||||
end;
|
||||
|
||||
constructor TSynEditMarkLineList.Create(AOwner: TSynEditMarkList);
|
||||
begin
|
||||
inherited Create;
|
||||
|
@ -483,7 +483,7 @@ type
|
||||
FParent, FLeft, FRight : TSynSizedDifferentialAVLNode; (* AVL Links *)
|
||||
FBalance : shortint; (* AVL Balance *)
|
||||
|
||||
(* Position: sores difference to parent value
|
||||
(* Position: stores difference to parent value
|
||||
*)
|
||||
FPositionOffset: Integer;
|
||||
|
||||
@ -494,6 +494,7 @@ type
|
||||
FSize: Integer;
|
||||
FLeftSizeSum: Integer;
|
||||
|
||||
property LeftSizeSum: Integer read FLeftSizeSum;
|
||||
{$IFDEF SynDebug}
|
||||
function Debug: String; virtual;
|
||||
{$ENDIF}
|
||||
@ -517,14 +518,18 @@ type
|
||||
|
||||
procedure AdjustLeftCount(AValue : Integer);
|
||||
procedure AdjustParentLeftCount(AValue : Integer);
|
||||
function GetSizesBeforeSum: Integer;
|
||||
|
||||
function Precessor: TSynSizedDifferentialAVLNode;
|
||||
function Successor: TSynSizedDifferentialAVLNode;
|
||||
function Precessor(var aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
function Successor(var aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
|
||||
function GetSizesBeforeSum: Integer;
|
||||
function GetPosition: Integer;
|
||||
end;
|
||||
|
||||
TSynSizedDiffAVLFindMode = (afmNil, afmCreate, afmPrev, afmNext);
|
||||
|
||||
{ TSynSizedDifferentialAVLTree }
|
||||
|
||||
TSynSizedDifferentialAVLTree = class
|
||||
@ -542,6 +547,8 @@ type
|
||||
procedure RemoveNode(ANode: TSynSizedDifferentialAVLNode);
|
||||
procedure BalanceAfterInsert(ANode: TSynSizedDifferentialAVLNode);
|
||||
procedure BalanceAfterDelete(ANode: TSynSizedDifferentialAVLNode);
|
||||
|
||||
function CreateNode(APosition: Integer): TSynSizedDifferentialAVLNode; virtual;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -554,6 +561,11 @@ type
|
||||
function Last: TSynSizedDifferentialAVLNode;
|
||||
function First(out aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
function Last(out aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
|
||||
function FindNodeAtLeftSize(ALeftSum: INteger;
|
||||
out aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
function FindNodeAtPosition(APosition: INteger; AMode: TSynSizedDiffAVLFindMode;
|
||||
out aStartPosition, aSizesBeforeSum : Integer): TSynSizedDifferentialAVLNode;
|
||||
end;
|
||||
|
||||
|
||||
@ -1912,6 +1924,18 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynSizedDifferentialAVLNode.GetPosition: Integer;
|
||||
var
|
||||
N: TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := FPositionOffset;
|
||||
N := FParent;
|
||||
while N <> nil do begin
|
||||
Result := Result + N.FPositionOffset;
|
||||
N := N.FParent;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynSizedDifferentialAVLNode.Precessor: TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := FLeft;
|
||||
@ -2430,6 +2454,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynSizedDifferentialAVLTree.CreateNode(APosition: Integer): TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := TSynSizedDifferentialAVLNode.Create;
|
||||
end;
|
||||
|
||||
constructor TSynSizedDifferentialAVLTree.Create;
|
||||
begin
|
||||
inherited;
|
||||
@ -2530,5 +2559,114 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynSizedDifferentialAVLTree.FindNodeAtLeftSize(ALeftSum: INteger; out
|
||||
aStartPosition, aSizesBeforeSum: Integer): TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := FRoot;
|
||||
aStartPosition := 0;
|
||||
aSizesBeforeSum := 0;
|
||||
if Result = nil then
|
||||
exit;
|
||||
|
||||
aStartPosition := Result.FPositionOffset;
|
||||
while Result <> nil do begin
|
||||
if ALeftSum < Result.FLeftSizeSum then begin
|
||||
Result := Result.FLeft;
|
||||
aStartPosition := aStartPosition + Result.FPositionOffset;
|
||||
continue;
|
||||
end;
|
||||
|
||||
ALeftSum := ALeftSum - Result.FLeftSizeSum;
|
||||
if ALeftSum < Result.FSize then begin
|
||||
break;
|
||||
end
|
||||
else begin
|
||||
ALeftSum := ALeftSum - Result.FSize;
|
||||
aSizesBeforeSum := aSizesBeforeSum + Result.FLeftSizeSum + Result.FSize;
|
||||
Result := Result.FRight;
|
||||
aStartPosition := aStartPosition + Result.FPositionOffset;
|
||||
continue;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSynSizedDifferentialAVLTree.FindNodeAtPosition(APosition: INteger;
|
||||
AMode: TSynSizedDiffAVLFindMode; out aStartPosition,
|
||||
aSizesBeforeSum: Integer): TSynSizedDifferentialAVLNode;
|
||||
|
||||
function CreateRoot: TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := CreateNode(APosition);
|
||||
Result.FPositionOffset := APosition;
|
||||
SetRoot(Result);
|
||||
end;
|
||||
|
||||
function CreateLeft(N: TSynSizedDifferentialAVLNode; ACurOffs: Integer): TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := CreateNode(APosition);
|
||||
Result.FPositionOffset := APosition;
|
||||
N.SetLeftChild(Result, -ACurOffs);
|
||||
BalanceAfterInsert(Result);
|
||||
end;
|
||||
|
||||
function CreateRight(N: TSynSizedDifferentialAVLNode; ACurOffs: Integer): TSynSizedDifferentialAVLNode;
|
||||
begin
|
||||
Result := CreateNode(APosition);
|
||||
Result.FPositionOffset := APosition;
|
||||
N.SetRightChild(Result, -ACurOffs);
|
||||
BalanceAfterInsert(Result);
|
||||
end;
|
||||
|
||||
begin
|
||||
aSizesBeforeSum := 0;
|
||||
aStartPosition := fRootOffset;
|
||||
|
||||
Result := FRoot;
|
||||
if (Result = nil) then begin
|
||||
if (AMode = afmCreate) then begin
|
||||
Result := CreateRoot;
|
||||
aStartPosition := aStartPosition + Result.FPositionOffset;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
|
||||
while (Result <> nil) do begin
|
||||
aStartPosition := aStartPosition + Result.FPositionOffset;
|
||||
|
||||
if aStartPosition > APosition then begin
|
||||
if (Result.FLeft = nil) then begin
|
||||
case AMode of
|
||||
afmCreate: Result := CreateLeft(Result, aStartPosition);
|
||||
afmNil: Result := nil;
|
||||
afmPrev: Result := Result.Precessor(aStartPosition, aStartPosition);
|
||||
// afmNext: Result already contains next node
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
Result := Result.FLeft;
|
||||
end
|
||||
|
||||
else
|
||||
if APosition = aStartPosition then begin
|
||||
break;
|
||||
end
|
||||
|
||||
else
|
||||
if aStartPosition < APosition then begin
|
||||
if (Result.FRight = nil) then begin
|
||||
case AMode of
|
||||
afmCreate: Result := CreateRight(Result, aStartPosition);
|
||||
afmNil: Result := nil;
|
||||
afmNext: Result := Result.Successor(aStartPosition, aStartPosition);
|
||||
// afmPrev : Result already contains prev node
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
aSizesBeforeSum := aSizesBeforeSum + Result.FLeftSizeSum + Result.FSize;
|
||||
Result := Result.FRight;
|
||||
end;
|
||||
end; // while
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user