mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-06 23:40:35 +02:00
codetools: finding and removing duplicate strings in define trees
git-svn-id: trunk@19913 -
This commit is contained in:
parent
b21b6284da
commit
8bc4612fcd
@ -141,6 +141,19 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(CaseInsensitive: boolean);
|
constructor Create(CaseInsensitive: boolean);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TStringTree }
|
||||||
|
|
||||||
|
TStringTree = class
|
||||||
|
public
|
||||||
|
Tree: TAVLTree;
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Clear;
|
||||||
|
function FindNode(const s: string): TAVLTreeNode; inline;
|
||||||
|
procedure ReplaceString(var s: string);
|
||||||
|
function CalcMemSize: PtrUInt;
|
||||||
|
end;
|
||||||
|
|
||||||
function CompareStringToStringItems(Data1, Data2: Pointer): integer;
|
function CompareStringToStringItems(Data1, Data2: Pointer): integer;
|
||||||
function CompareStringAndStringToStringTreeItem(Key, Data: Pointer): integer;
|
function CompareStringAndStringToStringTreeItem(Key, Data: Pointer): integer;
|
||||||
@ -154,6 +167,7 @@ function CompareFilenameAndFilenameToStringTreeItem(Key, Data: Pointer): integer
|
|||||||
function CompareFilenameToStringItemsI(Data1, Data2: Pointer): integer;
|
function CompareFilenameToStringItemsI(Data1, Data2: Pointer): integer;
|
||||||
function CompareFilenameAndFilenameToStringTreeItemI(Key, Data: Pointer): integer;
|
function CompareFilenameAndFilenameToStringTreeItemI(Key, Data: Pointer): integer;
|
||||||
|
|
||||||
|
function CompareAnsiStringPtrs(Data1, Data2: Pointer): integer;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -204,6 +218,11 @@ begin
|
|||||||
PStringToStringTreeItem(Data)^.Name);
|
PStringToStringTreeItem(Data)^.Name);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CompareAnsiStringPtrs(Data1, Data2: Pointer): integer;
|
||||||
|
begin
|
||||||
|
Result:=CompareStr(AnsiString(Data1),AnsiString(Data2));
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCodeXYPositions }
|
{ TCodeXYPositions }
|
||||||
|
|
||||||
function TCodeXYPositions.GetItems(Index: integer): PCodeXYPosition;
|
function TCodeXYPositions.GetItems(Index: integer): PCodeXYPosition;
|
||||||
@ -539,5 +558,65 @@ begin
|
|||||||
@CompareFilenameAndFilenameToStringTreeItem);
|
@CompareFilenameAndFilenameToStringTreeItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TStringTree }
|
||||||
|
|
||||||
|
constructor TStringTree.Create;
|
||||||
|
begin
|
||||||
|
Tree:=TAVLTree.Create(@CompareAnsiStringPtrs);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TStringTree.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
FreeAndNil(Tree);
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TStringTree.Clear;
|
||||||
|
var
|
||||||
|
Node: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Node:=Tree.FindLowest;
|
||||||
|
while Node<>nil do begin
|
||||||
|
AnsiString(Node.Data):='';
|
||||||
|
Node:=Tree.FindSuccessor(Node);
|
||||||
|
end;
|
||||||
|
Tree.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TStringTree.FindNode(const s: string): TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=Tree.Find(Pointer(s));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TStringTree.ReplaceString(var s: string);
|
||||||
|
var
|
||||||
|
Node: TAVLTreeNode;
|
||||||
|
h: String;
|
||||||
|
begin
|
||||||
|
Node:=FindNode(s);
|
||||||
|
if Node=nil then begin
|
||||||
|
// increase refcount
|
||||||
|
h:=s;
|
||||||
|
Tree.Add(Pointer(h));
|
||||||
|
Pointer(h):=nil; // keep refcount
|
||||||
|
end else
|
||||||
|
s:=AnsiString(Node.Data);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TStringTree.CalcMemSize: PtrUInt;
|
||||||
|
var
|
||||||
|
Node: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
Result:=PtrUInt(InstanceSize)
|
||||||
|
+PtrUInt(Tree.InstanceSize)
|
||||||
|
+PtrUInt(TAVLTreeNode.InstanceSize)*PtrUInt(Tree.Count);
|
||||||
|
Node:=Tree.FindLowest;
|
||||||
|
while Node<>nil do begin
|
||||||
|
inc(Result,MemSizeString(AnsiString(Node.Data)));
|
||||||
|
Node:=Tree.FindSuccessor(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, CodeToolsStrConsts, ExprEval, DirectoryCacher,
|
Classes, SysUtils, CodeToolsStrConsts, ExprEval, DirectoryCacher,
|
||||||
Laz_XMLCfg, AVL_Tree,
|
Laz_XMLCfg, AVL_Tree, CodeToolsStructs,
|
||||||
Process, KeywordFuncLists, FileProcs;
|
Process, KeywordFuncLists, FileProcs;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -354,6 +354,7 @@ type
|
|||||||
FDirectoryCachePool: TCTDirectoryCachePool;
|
FDirectoryCachePool: TCTDirectoryCachePool;
|
||||||
FFirstDefineTemplate: TDefineTemplate;
|
FFirstDefineTemplate: TDefineTemplate;
|
||||||
FCache: TAVLTree; // tree of TDirectoryDefines
|
FCache: TAVLTree; // tree of TDirectoryDefines
|
||||||
|
FDefineStrings: TStringTree;
|
||||||
FChangeStep: integer;
|
FChangeStep: integer;
|
||||||
FErrorDescription: string;
|
FErrorDescription: string;
|
||||||
FErrorTemplate: TDefineTemplate;
|
FErrorTemplate: TDefineTemplate;
|
||||||
@ -368,6 +369,7 @@ type
|
|||||||
function Calculate(DirDef: TDirectoryDefines): boolean;
|
function Calculate(DirDef: TDirectoryDefines): boolean;
|
||||||
procedure IncreaseChangeStep;
|
procedure IncreaseChangeStep;
|
||||||
procedure SetDirectoryCachePool(const AValue: TCTDirectoryCachePool);
|
procedure SetDirectoryCachePool(const AValue: TCTDirectoryCachePool);
|
||||||
|
procedure RemoveDoubles(Defines: TDirectoryDefines);
|
||||||
protected
|
protected
|
||||||
function FindDirectoryInCache(const Path: string): TDirectoryDefines;
|
function FindDirectoryInCache(const Path: string): TDirectoryDefines;
|
||||||
function GetDirDefinesForDirectory(const Path: string;
|
function GetDirDefinesForDirectory(const Path: string;
|
||||||
@ -1821,7 +1823,7 @@ begin
|
|||||||
Stats.Add('TDirectoryDefines',PtrUInt(InstanceSize)
|
Stats.Add('TDirectoryDefines',PtrUInt(InstanceSize)
|
||||||
+MemSizeString(Path));
|
+MemSizeString(Path));
|
||||||
if Values<>nil then
|
if Values<>nil then
|
||||||
Stats.Add('TDirectoryDefines.Values',Values.CalcMemSize);
|
Stats.Add('TDirectoryDefines.Values',Values.CalcMemSize(false,nil));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1888,7 +1890,8 @@ begin
|
|||||||
inherited Create;
|
inherited Create;
|
||||||
FFirstDefineTemplate:=nil;
|
FFirstDefineTemplate:=nil;
|
||||||
FCache:=TAVLTree.Create(@CompareDirectoryDefines);
|
FCache:=TAVLTree.Create(@CompareDirectoryDefines);
|
||||||
|
FDefineStrings:=TStringTree.Create;
|
||||||
|
|
||||||
FMacroFunctions:=TKeyWordFunctionList.Create;
|
FMacroFunctions:=TKeyWordFunctionList.Create;
|
||||||
FMacroFunctions.AddExtended('Ext',nil,@MacroFuncExtractFileExt);
|
FMacroFunctions.AddExtended('Ext',nil,@MacroFuncExtractFileExt);
|
||||||
FMacroFunctions.AddExtended('PATH',nil,@MacroFuncExtractFilePath);
|
FMacroFunctions.AddExtended('PATH',nil,@MacroFuncExtractFilePath);
|
||||||
@ -1904,6 +1907,7 @@ begin
|
|||||||
FMacroVariables.Free;
|
FMacroVariables.Free;
|
||||||
FMacroFunctions.Free;
|
FMacroFunctions.Free;
|
||||||
FCache.Free;
|
FCache.Free;
|
||||||
|
FreeAndNil(FDefineStrings);
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1953,6 +1957,7 @@ begin
|
|||||||
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] B ',ExpPath,' ');
|
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] B ',ExpPath,' ');
|
||||||
if Calculate(Result) then begin
|
if Calculate(Result) then begin
|
||||||
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] C success');
|
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] C success');
|
||||||
|
RemoveDoubles(Result);
|
||||||
FCache.Add(Result);
|
FCache.Add(Result);
|
||||||
end else begin
|
end else begin
|
||||||
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] D failed');
|
//DebugLn('[TDefineTree.GetDirDefinesForDirectory] D failed');
|
||||||
@ -1974,6 +1979,7 @@ begin
|
|||||||
FVirtualDirCache.Path:=VirtualDirectory;
|
FVirtualDirCache.Path:=VirtualDirectory;
|
||||||
if Calculate(FVirtualDirCache) then begin
|
if Calculate(FVirtualDirCache) then begin
|
||||||
//DebugLn('TDefineTree.GetDirDefinesForVirtualDirectory ');
|
//DebugLn('TDefineTree.GetDirDefinesForVirtualDirectory ');
|
||||||
|
RemoveDoubles(FVirtualDirCache);
|
||||||
end else begin
|
end else begin
|
||||||
FVirtualDirCache.Free;
|
FVirtualDirCache.Free;
|
||||||
FVirtualDirCache:=nil;
|
FVirtualDirCache:=nil;
|
||||||
@ -2029,6 +2035,7 @@ begin
|
|||||||
FVirtualDirCache:=nil;
|
FVirtualDirCache:=nil;
|
||||||
end;
|
end;
|
||||||
IncreaseChangeStep;
|
IncreaseChangeStep;
|
||||||
|
FDefineStrings.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDefineTree.DoPrepareTree;
|
procedure TDefineTree.DoPrepareTree;
|
||||||
@ -2621,6 +2628,12 @@ begin
|
|||||||
FDirectoryCachePool:=AValue;
|
FDirectoryCachePool:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDefineTree.RemoveDoubles(Defines: TDirectoryDefines);
|
||||||
|
begin
|
||||||
|
if Defines=nil then exit;
|
||||||
|
Defines.Values.RemoveDoubles(@FDefineStrings.ReplaceString);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDefineTree.Add(ADefineTemplate: TDefineTemplate);
|
procedure TDefineTree.Add(ADefineTemplate: TDefineTemplate);
|
||||||
// add as last
|
// add as last
|
||||||
var LastDefTempl: TDefineTemplate;
|
var LastDefTempl: TDefineTemplate;
|
||||||
@ -2797,6 +2810,8 @@ begin
|
|||||||
FFirstDefineTemplate.CalcMemSize(Stats);
|
FFirstDefineTemplate.CalcMemSize(Stats);
|
||||||
if FVirtualDirCache<>nil then
|
if FVirtualDirCache<>nil then
|
||||||
FVirtualDirCache.CalcMemSize(Stats);
|
FVirtualDirCache.CalcMemSize(Stats);
|
||||||
|
if FDefineStrings<>nil then
|
||||||
|
Stats.Add('TDefineTree.FDefineStrings',FDefineStrings.CalcMemSize);
|
||||||
if FCache<>nil then begin
|
if FCache<>nil then begin
|
||||||
Stats.Add('TDefineTree.FCache.Count',FCache.Count);
|
Stats.Add('TDefineTree.FCache.Count',FCache.Count);
|
||||||
Node:=FCache.FindLowest;
|
Node:=FCache.FindLowest;
|
||||||
|
@ -40,7 +40,7 @@ const
|
|||||||
|
|
||||||
type
|
type
|
||||||
TOnValuesChanged = procedure of object;
|
TOnValuesChanged = procedure of object;
|
||||||
|
TOnGetSameString = procedure(var s: string) of object;
|
||||||
ArrayOfAnsiString = ^AnsiString;
|
ArrayOfAnsiString = ^AnsiString;
|
||||||
|
|
||||||
|
|
||||||
@ -85,9 +85,10 @@ type
|
|||||||
function AsString: string;
|
function AsString: string;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
procedure RemoveDoubles(OnGetSameString: TOnGetSameString);
|
||||||
procedure ConsistencyCheck;
|
procedure ConsistencyCheck;
|
||||||
procedure WriteDebugReport;
|
procedure WriteDebugReport;
|
||||||
function CalcMemSize: PtrUInt;
|
function CalcMemSize(WithNamesAndValues: boolean = true; Original: TExpressionEvaluator = nil): PtrUInt;
|
||||||
property ChangeStamp: integer read FChangeStamp;
|
property ChangeStamp: integer read FChangeStamp;
|
||||||
procedure IncreaseChangeStamp; inline;
|
procedure IncreaseChangeStamp; inline;
|
||||||
end;
|
end;
|
||||||
@ -224,6 +225,16 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TExpressionEvaluator.RemoveDoubles(OnGetSameString: TOnGetSameString);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to FCount-1 do begin
|
||||||
|
OnGetSameString(FNames[i]);
|
||||||
|
OnGetSameString(FValues[i]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function TExpressionEvaluator.Eval(const Expression: string): string;
|
function TExpressionEvaluator.Eval(const Expression: string): string;
|
||||||
// 1 = true
|
// 1 = true
|
||||||
// 0 = syntax error
|
// 0 = syntax error
|
||||||
@ -757,16 +768,26 @@ begin
|
|||||||
ConsistencyCheck;
|
ConsistencyCheck;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TExpressionEvaluator.CalcMemSize: PtrUInt;
|
function TExpressionEvaluator.CalcMemSize(WithNamesAndValues: boolean;
|
||||||
|
Original: TExpressionEvaluator): PtrUInt;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
j: LongInt;
|
||||||
begin
|
begin
|
||||||
Result:=PtrUInt(InstanceSize)
|
Result:=PtrUInt(InstanceSize)
|
||||||
+MemSizeString(Expr)
|
+MemSizeString(Expr)
|
||||||
+SizeOf(Pointer)*FCount*2;
|
+SizeOf(Pointer)*FCount*2;
|
||||||
for i:=0 to FCount-1 do begin
|
if WithNamesAndValues then begin
|
||||||
inc(Result,MemSizeString(FNames[i]));
|
for i:=0 to FCount-1 do begin
|
||||||
inc(Result,MemSizeString(FValues[i]));
|
if Original<>nil then begin
|
||||||
|
j:=Original.IndexOfName(FNames[i],false);
|
||||||
|
if j>=0 then begin
|
||||||
|
if Pointer(FNames[i])=Pointer(Original.FNames[j]) then continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
inc(Result,MemSizeString(FNames[i]));
|
||||||
|
inc(Result,MemSizeString(FValues[i]));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1416,7 +1416,7 @@ begin
|
|||||||
FLinkCapacity*SizeOf(TSourceLink));
|
FLinkCapacity*SizeOf(TSourceLink));
|
||||||
if FInitValues<>nil then
|
if FInitValues<>nil then
|
||||||
Stats.Add('TLinkScanner.FInitValues',
|
Stats.Add('TLinkScanner.FInitValues',
|
||||||
FInitValues.CalcMemSize);
|
FInitValues.CalcMemSize(false)); // FInitValues are copies of strings of TDefineTree
|
||||||
if FSourceChangeSteps<>nil then
|
if FSourceChangeSteps<>nil then
|
||||||
Stats.Add('TLinkScanner.FSourceChangeSteps',
|
Stats.Add('TLinkScanner.FSourceChangeSteps',
|
||||||
FSourceChangeSteps.InstanceSize
|
FSourceChangeSteps.InstanceSize
|
||||||
@ -1426,7 +1426,7 @@ begin
|
|||||||
FIncludeStack.InstanceSize+FIncludeStack.Capacity*SizeOf(TSourceLink));
|
FIncludeStack.InstanceSize+FIncludeStack.Capacity*SizeOf(TSourceLink));
|
||||||
if Values<>nil then
|
if Values<>nil then
|
||||||
Stats.Add('TLinkScanner.Values',
|
Stats.Add('TLinkScanner.Values',
|
||||||
Values.CalcMemSize);
|
Values.CalcMemSize(true,FInitValues));
|
||||||
if FMissingIncludeFiles<>nil then
|
if FMissingIncludeFiles<>nil then
|
||||||
Stats.Add('TLinkScanner.FMissingIncludeFiles',
|
Stats.Add('TLinkScanner.FMissingIncludeFiles',
|
||||||
FMissingIncludeFiles.InstanceSize);
|
FMissingIncludeFiles.InstanceSize);
|
||||||
|
Loading…
Reference in New Issue
Block a user