mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 19:39:17 +02:00
codetools: saving includelinks compressed
git-svn-id: trunk@25688 -
This commit is contained in:
parent
b35fff5bcc
commit
5c3930c99d
@ -38,11 +38,11 @@ uses
|
|||||||
{$IFDEF MEM_CHECK}
|
{$IFDEF MEM_CHECK}
|
||||||
MemCheck,
|
MemCheck,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Classes, SysUtils, SourceLog, LinkScanner, FileProcs,
|
Math, Classes, SysUtils, SourceLog, LinkScanner, FileProcs,
|
||||||
Avl_Tree, Laz_XMLCfg;
|
Avl_Tree, Laz_XMLCfg;
|
||||||
|
|
||||||
const
|
const
|
||||||
IncludeLinksFileVersion = 1;
|
IncludeLinksFileVersion = 2;
|
||||||
type
|
type
|
||||||
TCodeCache = class;
|
TCodeCache = class;
|
||||||
|
|
||||||
@ -177,11 +177,13 @@ type
|
|||||||
function LastIncludedByFile(const IncludeFilename: string): string;
|
function LastIncludedByFile(const IncludeFilename: string): string;
|
||||||
function LoadFile(const AFilename: string): TCodeBuffer;
|
function LoadFile(const AFilename: string): TCodeBuffer;
|
||||||
procedure RemoveCodeBuffer(Buffer: TCodeBuffer);
|
procedure RemoveCodeBuffer(Buffer: TCodeBuffer);
|
||||||
|
procedure LoadIncludeLinksDataFromList(List: TStrings);
|
||||||
function LoadIncludeLinksFromFile(const AFilename: string): boolean;
|
function LoadIncludeLinksFromFile(const AFilename: string): boolean;
|
||||||
function LoadIncludeLinksFromXML(XMLConfig: TXMLConfig;
|
function LoadIncludeLinksFromXML(XMLConfig: TXMLConfig;
|
||||||
const XMLPath: string): boolean;
|
const XMLPath: string): boolean;
|
||||||
function SaveBufferAs(OldBuffer: TCodeBuffer; const AFilename: string;
|
function SaveBufferAs(OldBuffer: TCodeBuffer; const AFilename: string;
|
||||||
out NewBuffer: TCodeBuffer): boolean;
|
out NewBuffer: TCodeBuffer): boolean;
|
||||||
|
procedure SaveIncludeLinksDataToList(List: TStrings);
|
||||||
function SaveIncludeLinksToFile(const AFilename: string;
|
function SaveIncludeLinksToFile(const AFilename: string;
|
||||||
OnlyIfChanged: boolean): boolean;
|
OnlyIfChanged: boolean): boolean;
|
||||||
function SaveIncludeLinksToXML(XMLConfig: TXMLConfig;
|
function SaveIncludeLinksToXML(XMLConfig: TXMLConfig;
|
||||||
@ -358,6 +360,96 @@ begin
|
|||||||
FItems.Remove(Buffer);
|
FItems.Remove(Buffer);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCodeCache.LoadIncludeLinksDataFromList(List: TStrings);
|
||||||
|
{ First line is the base date as DateToCfgStr
|
||||||
|
|
||||||
|
The following lines are compressed. Each line starting with a number of
|
||||||
|
characters to use from the previous line. Then a colon and the rest of the
|
||||||
|
line.
|
||||||
|
Each include link has two lines, the first is the IncludeFilename, the
|
||||||
|
second the the IncludedByFile plus semicolon and the age in days.
|
||||||
|
}
|
||||||
|
var
|
||||||
|
BaseDate: TDateTime;
|
||||||
|
LastLine: string;
|
||||||
|
Index: integer;
|
||||||
|
|
||||||
|
function NextLine: string;
|
||||||
|
begin
|
||||||
|
// skip empty lines
|
||||||
|
repeat
|
||||||
|
if Index>=List.Count then begin
|
||||||
|
Result:='';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result:=List[Index];
|
||||||
|
inc(Index);
|
||||||
|
until Result<>'';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function NextUncompressedLine: string;
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
Same: Integer;
|
||||||
|
begin
|
||||||
|
Result:=NextLine;
|
||||||
|
p:=1;
|
||||||
|
Same:=0;
|
||||||
|
while (p<=length(Result)) and (Result[p] in ['0'..'9']) do begin
|
||||||
|
Same:=Same*10+ord(Result[p])-ord('0');
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
inc(p);
|
||||||
|
Result:=copy(LastLine,1,Same)+copy(Result,p,length(Result));
|
||||||
|
LastLine:=Result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
IncludeFilename: String;
|
||||||
|
IncludedByFile: String;
|
||||||
|
p: Longint;
|
||||||
|
Days: LongInt;
|
||||||
|
Link: TIncludedByLink;
|
||||||
|
LastTimeUsed: TDateTime;
|
||||||
|
CurrDate: TDateTime;
|
||||||
|
begin
|
||||||
|
FIncludeLinks.FreeAndClear;
|
||||||
|
Index:=0;
|
||||||
|
CurrDate:=Date;
|
||||||
|
LastLine:='';
|
||||||
|
if not CfgStrToDate(NextLine,BaseDate) then BaseDate:=Date;
|
||||||
|
repeat
|
||||||
|
IncludeFilename:=NextUncompressedLine;
|
||||||
|
if IncludeFilename='' then exit;
|
||||||
|
IncludedByFile:=NextUncompressedLine;
|
||||||
|
if IncludedByFile='' then begin
|
||||||
|
debugln(['TCodeCache.LoadIncludeLinksDataFromList missing IncludedByFile: IncludeFilename=',IncludeFilename,' line=',Index]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
p:=System.Pos(';',IncludedByFile);
|
||||||
|
if p<1 then begin
|
||||||
|
debugln(['TCodeCache.LoadIncludeLinksDataFromList missing age in IncludedByFile line: ',IncludedByFile,' line=',Index]);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Days:=StrToIntDef(copy(IncludedByFile,p+1,length(IncludedByFile)),0);
|
||||||
|
IncludedByFile:=copy(IncludedByFile,1,p-1);
|
||||||
|
LastTimeUsed:=BaseDate-Days;
|
||||||
|
//debugln(['TCodeCache.LoadIncludeLinksDataFromList ',IncludeFilename,' ',IncludedByFile,' ',LastTimeUsed]);
|
||||||
|
if (FExpirationTimeInDays<=0)
|
||||||
|
or (CurrDate-LastTimeUsed<=FExpirationTimeInDays) then begin
|
||||||
|
Link:=FindIncludeLinkNode(IncludeFilename);
|
||||||
|
if Link=nil then begin
|
||||||
|
Link:=TIncludedByLink.Create(IncludeFilename,IncludedByFile,
|
||||||
|
BaseDate-Days);
|
||||||
|
FIncludeLinks.Add(Link);
|
||||||
|
end else if Link.LastTimeUsed<=LastTimeUsed then begin
|
||||||
|
Link.IncludedByFile:=IncludedByFile;
|
||||||
|
Link.LastTimeUsed:=LastTimeUsed;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
until false;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCodeCache.CreateFile(const AFilename: string): TCodeBuffer;
|
function TCodeCache.CreateFile(const AFilename: string): TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
Result:=FindFile(AFileName);
|
Result:=FindFile(AFileName);
|
||||||
@ -420,6 +512,58 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCodeCache.SaveIncludeLinksDataToList(List: TStrings);
|
||||||
|
{ First line is the base date as DateToCfgStr
|
||||||
|
|
||||||
|
The following lines are compressed. Each line starting with a number of
|
||||||
|
characters to use from the previous line. Then a colon and the rest of the
|
||||||
|
line.
|
||||||
|
Each include link has two lines, the first is the IncludeFilename, the
|
||||||
|
second the the IncludedByFile plus semicolon and the age in days.
|
||||||
|
}
|
||||||
|
var
|
||||||
|
LastLine: String;
|
||||||
|
CurrDate: TDateTime;
|
||||||
|
ExpirationTime: TDateTime;
|
||||||
|
|
||||||
|
procedure AddLine(Line: string);
|
||||||
|
var
|
||||||
|
p: Integer;
|
||||||
|
begin
|
||||||
|
p:=1;
|
||||||
|
while (p<=length(Line)) and (p<=length(LastLine))
|
||||||
|
and (Line[p]=LastLine[p]) do
|
||||||
|
inc(p);
|
||||||
|
List.Add(IntToStr(p-1)+':'+copy(Line,p,length(Line)));
|
||||||
|
LastLine:=Line;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure SaveLinkTree(ANode: TAVLTreeNode);
|
||||||
|
var
|
||||||
|
ALink: TIncludedByLink;
|
||||||
|
DiffTime: TDateTime;
|
||||||
|
begin
|
||||||
|
if ANode=nil then exit;
|
||||||
|
SaveLinkTree(ANode.Left);
|
||||||
|
ALink:=TIncludedByLink(ANode.Data);
|
||||||
|
DiffTime:=CurrDate-ALink.LastTimeUsed;
|
||||||
|
if (FExpirationTimeInDays<=0) or (DiffTime<ExpirationTime) then begin
|
||||||
|
AddLine(ALink.IncludeFilename);
|
||||||
|
AddLine(ALink.IncludedByFile+';'+IntToStr(round(CurrDate-ALink.LastTimeUsed)));
|
||||||
|
end;
|
||||||
|
SaveLinkTree(ANode.Right);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
UpdateIncludeLinks;
|
||||||
|
if FIncludeLinks.Count=0 then exit;
|
||||||
|
ExpirationTime:=TDateTime(FExpirationTimeInDays);
|
||||||
|
LastLine:='';
|
||||||
|
CurrDate:=Date;
|
||||||
|
List.Add(DateToCfgStr(CurrDate));
|
||||||
|
SaveLinkTree(FIncludeLinks.Root);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCodeCache.LastIncludedByFile(const IncludeFilename: string): string;
|
function TCodeCache.LastIncludedByFile(const IncludeFilename: string): string;
|
||||||
var Code: TCodeBuffer;
|
var Code: TCodeBuffer;
|
||||||
begin
|
begin
|
||||||
@ -547,8 +691,7 @@ begin
|
|||||||
ANode:=FIncludeLinks.Root;
|
ANode:=FIncludeLinks.Root;
|
||||||
while ANode<>nil do begin
|
while ANode<>nil do begin
|
||||||
Result:=TIncludedByLink(ANode.Data);
|
Result:=TIncludedByLink(ANode.Data);
|
||||||
cmp:=CompareFilenames(
|
cmp:=CompareFilenames(IncludeFilename,Result.IncludeFilename);
|
||||||
IncludeFilename,Result.IncludeFilename);
|
|
||||||
if cmp<0 then ANode:=ANode.Left
|
if cmp<0 then ANode:=ANode.Left
|
||||||
else if cmp>0 then ANode:=ANode.Right
|
else if cmp>0 then ANode:=ANode.Right
|
||||||
else begin
|
else begin
|
||||||
@ -562,7 +705,7 @@ function TCodeCache.FindIncludeLinkAVLNode(const IncludeFilename: string
|
|||||||
): TAVLTreeNode;
|
): TAVLTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=FIncludeLinks.FindKey(@IncludeFilename,
|
Result:=FIncludeLinks.FindKey(@IncludeFilename,
|
||||||
@ComparePAnsiStringWithIncludedByLink);
|
@ComparePAnsiStringWithIncludedByLink);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeCache.FindIncludeLink(const IncludeFilename: string): string;
|
function TCodeCache.FindIncludeLink(const IncludeFilename: string): string;
|
||||||
@ -631,6 +774,7 @@ begin
|
|||||||
and FileExistsCached(AFilename)
|
and FileExistsCached(AFilename)
|
||||||
and (FileAgeCached(AFilename)=fLastIncludeLinkFileAge)
|
and (FileAgeCached(AFilename)=fLastIncludeLinkFileAge)
|
||||||
then begin
|
then begin
|
||||||
|
//debugln(['TCodeCache.SaveIncludeLinksToFile file valid']);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
XMLConfig:=TXMLConfig.CreateClean(AFilename);
|
XMLConfig:=TXMLConfig.CreateClean(AFilename);
|
||||||
@ -672,46 +816,20 @@ end;
|
|||||||
function TCodeCache.SaveIncludeLinksToXML(XMLConfig: TXMLConfig;
|
function TCodeCache.SaveIncludeLinksToXML(XMLConfig: TXMLConfig;
|
||||||
const XMLPath: string): boolean;
|
const XMLPath: string): boolean;
|
||||||
var
|
var
|
||||||
Index: integer;
|
List: TStringList;
|
||||||
CurrDate: TDateTime;
|
|
||||||
ExpirationTime: TDateTime;
|
|
||||||
|
|
||||||
procedure SaveLinkTree(ANode: TAVLTreeNode);
|
|
||||||
var ALink: TIncludedByLink;
|
|
||||||
APath: string;
|
|
||||||
DiffTime: TDateTime;
|
|
||||||
begin
|
|
||||||
if ANode=nil then exit;
|
|
||||||
SaveLinkTree(ANode.Left);
|
|
||||||
ALink:=TIncludedByLink(ANode.Data);
|
|
||||||
DiffTime:=CurrDate-ALink.LastTimeUsed;
|
|
||||||
if (FExpirationTimeInDays<=0) or (DiffTime<ExpirationTime) then begin
|
|
||||||
APath:=XMLPath+'IncludeLinks/Link'+IntToStr(Index)+'/';
|
|
||||||
XMLConfig.SetValue(APath+'IncludeFilename/Value',ALink.IncludeFilename);
|
|
||||||
XMLConfig.SetValue(APath+'IncludedByFilename/Value',ALink.IncludedByFile);
|
|
||||||
XMLConfig.SetValue(APath+'LastTimeUsed/Value',
|
|
||||||
DateToCfgStr(ALink.LastTimeUsed));
|
|
||||||
inc(Index);
|
|
||||||
end;
|
|
||||||
SaveLinkTree(ANode.Right);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
UpdateIncludeLinks;
|
||||||
|
XMLConfig.SetValue(XMLPath+'IncludeLinks/Version',IncludeLinksFileVersion);
|
||||||
|
XMLConfig.SetDeleteValue(XMLPath+'IncludeLinks/ExpirationTimeInDays',
|
||||||
|
FExpirationTimeInDays,0);
|
||||||
|
List:=TStringList.Create;
|
||||||
try
|
try
|
||||||
CurrDate:=Date;
|
SaveIncludeLinksDataToList(List);
|
||||||
ExpirationTime:=TDateTime(FExpirationTimeInDays);
|
XMLConfig.SetDeleteValue(XMLPath+'IncludeLinks/Data',List.Text,'');
|
||||||
UpdateIncludeLinks;
|
finally
|
||||||
XMLConfig.SetValue(XMLPath+'IncludeLinks/Version',IncludeLinksFileVersion);
|
List.Free;
|
||||||
XMLConfig.SetDeleteValue(XMLPath+'IncludeLinks/ExpirationTimeInDays',
|
|
||||||
FExpirationTimeInDays,0);
|
|
||||||
XMLConfig.SetValue(XMLPath+'IncludeLinks/BaseDate',DateToCfgStr(CurrDate));
|
|
||||||
Index:=0;
|
|
||||||
SaveLinkTree(FIncludeLinks.Root);
|
|
||||||
XMLConfig.SetDeleteValue(XMLPath+'IncludeLinks/Count',Index,0);
|
|
||||||
Result:=true;
|
|
||||||
except
|
|
||||||
Result:=false;
|
|
||||||
end;
|
end;
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeCache.LoadIncludeLinksFromXML(XMLConfig: TXMLConfig;
|
function TCodeCache.LoadIncludeLinksFromXML(XMLConfig: TXMLConfig;
|
||||||
@ -722,44 +840,49 @@ var LinkCnt, i: integer;
|
|||||||
NewLink: TIncludedByLink;
|
NewLink: TIncludedByLink;
|
||||||
CurrDateStr: String;
|
CurrDateStr: String;
|
||||||
FileVersion: longint;
|
FileVersion: longint;
|
||||||
|
List: TStringList;
|
||||||
begin
|
begin
|
||||||
try
|
FIncludeLinks.FreeAndClear;
|
||||||
FIncludeLinks.FreeAndClear;
|
|
||||||
FileVersion:=XMLConfig.GetValue(XMLPath+'IncludeLinks/Version',0);
|
FileVersion:=XMLConfig.GetValue(XMLPath+'IncludeLinks/Version',0);
|
||||||
FExpirationTimeInDays:=XMLConfig.GetValue(
|
FExpirationTimeInDays:=XMLConfig.GetValue(
|
||||||
XMLPath+'IncludeLinks/ExpirationTimeInDays',
|
XMLPath+'IncludeLinks/ExpirationTimeInDays',
|
||||||
FExpirationTimeInDays);
|
FExpirationTimeInDays);
|
||||||
//debugln(['TCodeCache.LoadIncludeLinksFromXML FExpirationTimeInDays=',FExpirationTimeInDays]);
|
if FileVersion=2 then begin
|
||||||
|
List:=TStringList.Create;
|
||||||
|
try
|
||||||
|
List.Text:=XMLConfig.GetValue(XMLPath+'IncludeLinks/Data','');
|
||||||
|
LoadIncludeLinksDataFromList(List);
|
||||||
|
finally
|
||||||
|
List.Free;
|
||||||
|
end;
|
||||||
|
end else if FileVersion<=1 then begin
|
||||||
CurrDate:=Date;
|
CurrDate:=Date;
|
||||||
CurrDateStr:=DateToCfgStr(CurrDate);
|
CurrDateStr:=DateToCfgStr(CurrDate);
|
||||||
if FileVersion<=1 then begin
|
LinkCnt:=XMLConfig.GetValue(XMLPath+'IncludeLinks/Count',0);
|
||||||
LinkCnt:=XMLConfig.GetValue(XMLPath+'IncludeLinks/Count',0);
|
for i:=0 to LinkCnt-1 do begin
|
||||||
for i:=0 to LinkCnt-1 do begin
|
APath:=XMLPath+'IncludeLinks/Link'+IntToStr(i)+'/';
|
||||||
APath:=XMLPath+'IncludeLinks/Link'+IntToStr(i)+'/';
|
if not CfgStrToDate(XMLConfig.GetValue(APath+'LastTimeUsed/Value',
|
||||||
if not CfgStrToDate(XMLConfig.GetValue(APath+'LastTimeUsed/Value',
|
CurrDateStr),LastTimeUsed)
|
||||||
CurrDateStr),LastTimeUsed)
|
then begin
|
||||||
then begin
|
debugln(['TCodeCache.LoadIncludeLinksFromXML invalid date: ',XMLConfig.GetValue(APath+'LastTimeUsed/Value','')]);
|
||||||
debugln(['TCodeCache.LoadIncludeLinksFromXML invalid date: ',XMLConfig.GetValue(APath+'LastTimeUsed/Value','')]);
|
LastTimeUsed:=CurrDate;
|
||||||
LastTimeUsed:=CurrDate;
|
end;
|
||||||
end;
|
// ToDo: check if link has expired
|
||||||
// ToDo: check if link has expired
|
|
||||||
|
|
||||||
IncludeFilename:=XMLConfig.GetValue(APath+'IncludeFilename/Value','');
|
IncludeFilename:=XMLConfig.GetValue(APath+'IncludeFilename/Value','');
|
||||||
//debugln(['TCodeCache.LoadIncludeLinksFromXML CurrDate=',DateToStr(CurrDate),' xml=',XMLConfig.GetValue(APath+'LastTimeUsed/Value',''),' Days=',CurrDate-LastTimeUsed,' ',IncludeFilename]);
|
//debugln(['TCodeCache.LoadIncludeLinksFromXML CurrDate=',DateToStr(CurrDate),' xml=',XMLConfig.GetValue(APath+'LastTimeUsed/Value',''),' Days=',CurrDate-LastTimeUsed,' ',IncludeFilename]);
|
||||||
if IncludeFilename='' then continue;
|
if IncludeFilename='' then continue;
|
||||||
IncludedByFile:=XMLConfig.GetValue(APath+'IncludedByFilename/Value','');
|
IncludedByFile:=XMLConfig.GetValue(APath+'IncludedByFilename/Value','');
|
||||||
if (FExpirationTimeInDays<=0)
|
if (FExpirationTimeInDays<=0)
|
||||||
or (CurrDate-LastTimeUsed<=FExpirationTimeInDays) then begin
|
or (CurrDate-LastTimeUsed<=FExpirationTimeInDays) then begin
|
||||||
NewLink:=TIncludedByLink.Create(IncludeFilename,IncludedByFile,
|
NewLink:=TIncludedByLink.Create(IncludeFilename,IncludedByFile,
|
||||||
LastTimeUsed);
|
LastTimeUsed);
|
||||||
FIncludeLinks.Add(NewLink);
|
FIncludeLinks.Add(NewLink);
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
|
||||||
except
|
|
||||||
Result:=false;
|
|
||||||
end;
|
end;
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeCache.ConsistencyCheck;
|
procedure TCodeCache.ConsistencyCheck;
|
||||||
|
@ -444,6 +444,7 @@ begin
|
|||||||
{$ELSE}
|
{$ELSE}
|
||||||
Laz_XMLWrite.WriteXMLFile(ADoc,AFileName);
|
Laz_XMLWrite.WriteXMLFile(ADoc,AFileName);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
InvalidateFileStateCache(AFileName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TXMLConfig.FreeDoc;
|
procedure TXMLConfig.FreeDoc;
|
||||||
@ -570,8 +571,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
doc:=nil;
|
doc:=nil;
|
||||||
if (not fDoNotLoadFromFile) and FileExistsCached(AFilename) then
|
if (not fDoNotLoadFromFile) and FileExistsCached(Filename) then
|
||||||
ReadXMLFile(doc,AFilename)
|
ReadXMLFile(doc,Filename)
|
||||||
else if fAutoLoadFromSource<>'' then begin
|
else if fAutoLoadFromSource<>'' then begin
|
||||||
ms:=TMemoryStream.Create;
|
ms:=TMemoryStream.Create;
|
||||||
try
|
try
|
||||||
|
Loading…
Reference in New Issue
Block a user