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