mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-30 02:02:53 +02:00
codetools: directory cacher: store time
git-svn-id: trunk@30871 -
This commit is contained in:
parent
7b0df7dac3
commit
074d76af61
@ -103,18 +103,22 @@ type
|
|||||||
FileTimeStamp: cardinal;
|
FileTimeStamp: cardinal;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TCTDirectoryListingTime = longint;
|
||||||
|
PCTDirectoryListingTime = ^TCTDirectoryListingTime;
|
||||||
|
|
||||||
{ TCTDirectoryListing }
|
{ TCTDirectoryListing }
|
||||||
|
|
||||||
TCTDirectoryListing = class
|
TCTDirectoryListing = class
|
||||||
public
|
public
|
||||||
FileTimeStamp: cardinal;
|
FileTimeStamp: cardinal;
|
||||||
Names: PChar; // all filenames separated with #0
|
Files: PChar; // all filenames: each: time:TCTDirectoryListingTime+filename+#0
|
||||||
NameCount: integer; // number of filenames
|
Count: integer; // number of filenames
|
||||||
NamesLength: PtrInt; // length of Names in bytes
|
Size: PtrInt; // length of Names in bytes
|
||||||
NameStarts: PInteger; // offsets in 'Names'
|
Starts: PInteger; // offsets in 'Names'
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
function CalcMemSize: PtrUInt;
|
function CalcMemSize: PtrUInt;
|
||||||
|
function GetFilename(Index: integer): PChar;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCTOnIterateFile = procedure(const Filename: string) of object;
|
TCTOnIterateFile = procedure(const Filename: string) of object;
|
||||||
@ -492,13 +496,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCTDirectoryCache.UpdateListing;
|
procedure TCTDirectoryCache.UpdateListing;
|
||||||
|
type
|
||||||
|
TWorkFileInfo = record
|
||||||
|
FileName: string;
|
||||||
|
Time: TCTDirectoryListingTime;
|
||||||
|
end;
|
||||||
|
PWorkFileInfo = ^TWorkFileInfo;
|
||||||
|
|
||||||
var
|
var
|
||||||
WorkingListing: PAnsiString;
|
WorkingListing: PWorkFileInfo;
|
||||||
WorkingListingCapacity, WorkingListingCount: integer;
|
WorkingListingCapacity, WorkingListingCount: integer;
|
||||||
|
WorkingItem: PWorkFileInfo;
|
||||||
FileInfo: TSearchRec;
|
FileInfo: TSearchRec;
|
||||||
TotalLen: Integer;
|
TotalLen: Integer;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
p: Integer;
|
p: PChar;
|
||||||
CurFilenameLen: Integer;
|
CurFilenameLen: Integer;
|
||||||
NewCapacity: Integer;
|
NewCapacity: Integer;
|
||||||
begin
|
begin
|
||||||
@ -530,12 +542,14 @@ begin
|
|||||||
NewCapacity:=WorkingListingCapacity*2
|
NewCapacity:=WorkingListingCapacity*2
|
||||||
else
|
else
|
||||||
NewCapacity:=8;
|
NewCapacity:=8;
|
||||||
ReAllocMem(WorkingListing,SizeOf(Pointer)*NewCapacity);
|
ReAllocMem(WorkingListing,SizeOf(TWorkFileInfo)*NewCapacity);
|
||||||
FillChar(WorkingListing[WorkingListingCount],
|
FillChar(WorkingListing[WorkingListingCount],
|
||||||
SizeOf(Pointer)*(NewCapacity-WorkingListingCapacity),0);
|
SizeOf(TWorkFileInfo)*(NewCapacity-WorkingListingCapacity),0);
|
||||||
WorkingListingCapacity:=NewCapacity;
|
WorkingListingCapacity:=NewCapacity;
|
||||||
end;
|
end;
|
||||||
WorkingListing[WorkingListingCount]:=FileInfo.Name;
|
WorkingItem:=@WorkingListing[WorkingListingCount];
|
||||||
|
WorkingItem^.Time:=FileInfo.Time;
|
||||||
|
WorkingItem^.FileName:=FileInfo.Name;
|
||||||
inc(WorkingListingCount);
|
inc(WorkingListingCount);
|
||||||
until FindNextUTF8(FileInfo)<>0;
|
until FindNextUTF8(FileInfo)<>0;
|
||||||
end;
|
end;
|
||||||
@ -550,25 +564,30 @@ begin
|
|||||||
// create listing
|
// create listing
|
||||||
TotalLen:=0;
|
TotalLen:=0;
|
||||||
for i:=0 to WorkingListingCount-1 do
|
for i:=0 to WorkingListingCount-1 do
|
||||||
inc(TotalLen,length(WorkingListing[i])+1);
|
inc(TotalLen,length(WorkingListing[i].FileName)+1+SizeOf(TCTDirectoryListingTime));
|
||||||
GetMem(FListing.Names,TotalLen);
|
GetMem(FListing.Files,TotalLen);
|
||||||
FListing.NamesLength:=TotalLen;
|
FListing.Size:=TotalLen;
|
||||||
FListing.NameCount:=WorkingListingCount;
|
FListing.Count:=WorkingListingCount;
|
||||||
GetMem(FListing.NameStarts,SizeOf(PChar)*WorkingListingCount);
|
GetMem(FListing.Starts,SizeOf(PChar)*WorkingListingCount);
|
||||||
p:=0;
|
p:=FListing.Files;
|
||||||
for i:=0 to WorkingListingCount-1 do begin
|
for i:=0 to WorkingListingCount-1 do begin
|
||||||
CurFilenameLen:=length(WorkingListing[i]);
|
FListing.Starts[i]:=p-FListing.Files;
|
||||||
|
WorkingItem:=@WorkingListing[i];
|
||||||
|
// time
|
||||||
|
PCTDirectoryListingTime(p)^:=WorkingItem^.Time;
|
||||||
|
inc(p,SizeOf(TCTDirectoryListingTime));
|
||||||
|
// filename
|
||||||
|
CurFilenameLen:=length(WorkingItem^.FileName);
|
||||||
if CurFilenameLen>0 then begin
|
if CurFilenameLen>0 then begin
|
||||||
FListing.NameStarts[i]:=p;
|
System.Move(WorkingItem^.FileName[1],p^,CurFilenameLen);
|
||||||
System.Move(WorkingListing[i][1],FListing.Names[p],CurFilenameLen);
|
|
||||||
inc(p,CurFilenameLen);
|
inc(p,CurFilenameLen);
|
||||||
end;
|
end;
|
||||||
FListing.Names[p]:=#0;
|
p^:=#0;
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
for i:=0 to WorkingListingCount-1 do
|
for i:=0 to WorkingListingCount-1 do
|
||||||
WorkingListing[i]:='';
|
WorkingListing[i].FileName:='';
|
||||||
ReAllocMem(WorkingListing,0);
|
ReAllocMem(WorkingListing,0);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -770,17 +789,19 @@ var
|
|||||||
m: Integer;
|
m: Integer;
|
||||||
cmp: LongInt;
|
cmp: LongInt;
|
||||||
CurFilename: PChar;
|
CurFilename: PChar;
|
||||||
|
Files: PChar;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
if ShortFilename='' then exit;
|
if ShortFilename='' then exit;
|
||||||
if Directory<>'' then begin
|
if Directory<>'' then begin
|
||||||
UpdateListing;
|
UpdateListing;
|
||||||
if (FListing.Names=nil) then exit;
|
Files:=FListing.Files;
|
||||||
|
if Files=nil then exit;
|
||||||
l:=0;
|
l:=0;
|
||||||
r:=FListing.NameCount-1;
|
r:=FListing.Count-1;
|
||||||
while r>=l do begin
|
while r>=l do begin
|
||||||
m:=(l+r) shr 1;
|
m:=(l+r) shr 1;
|
||||||
CurFilename:=@FListing.Names[FListing.NameStarts[m]];
|
CurFilename:=@Files[FListing.Starts[m]+SizeOf(TCTDirectoryListingTime)];
|
||||||
case FileCase of
|
case FileCase of
|
||||||
ctsfcDefault:
|
ctsfcDefault:
|
||||||
{$IFDEF CaseInsensitiveFilenames}
|
{$IFDEF CaseInsensitiveFilenames}
|
||||||
@ -809,6 +830,8 @@ end;
|
|||||||
|
|
||||||
function TCTDirectoryCache.FindUnitSource(const AUnitName: string;
|
function TCTDirectoryCache.FindUnitSource(const AUnitName: string;
|
||||||
AnyCase: boolean): string;
|
AnyCase: boolean): string;
|
||||||
|
const
|
||||||
|
NameOffset = SizeOf(TCTDirectoryListingTime);
|
||||||
var
|
var
|
||||||
l: Integer;
|
l: Integer;
|
||||||
r: Integer;
|
r: Integer;
|
||||||
@ -816,6 +839,7 @@ var
|
|||||||
cmp: LongInt;
|
cmp: LongInt;
|
||||||
CurFilename: PChar;
|
CurFilename: PChar;
|
||||||
CurFilenameLen: LongInt;
|
CurFilenameLen: LongInt;
|
||||||
|
Files: PChar;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
//if (CompareText(AUnitName,'AddFileToAPackageDlg')=0) {and (System.Pos('packager',directory)>0)} then
|
//if (CompareText(AUnitName,'AddFileToAPackageDlg')=0) {and (System.Pos('packager',directory)>0)} then
|
||||||
@ -823,16 +847,17 @@ begin
|
|||||||
if AUnitName='' then exit;
|
if AUnitName='' then exit;
|
||||||
if Directory<>'' then begin
|
if Directory<>'' then begin
|
||||||
UpdateListing;
|
UpdateListing;
|
||||||
if (FListing.Names=nil) then exit;
|
Files:=FListing.Files;
|
||||||
|
if Files=nil then exit;
|
||||||
// binary search the nearest filename
|
// binary search the nearest filename
|
||||||
//if (CompareText(AUnitName,'AddFileToAPackageDlg')=0) and (System.Pos('packager',directory)>0) then
|
//if (CompareText(AUnitName,'AddFileToAPackageDlg')=0) and (System.Pos('packager',directory)>0) then
|
||||||
// WriteListing;
|
// WriteListing;
|
||||||
|
|
||||||
l:=0;
|
l:=0;
|
||||||
r:=FListing.NameCount-1;
|
r:=FListing.Count-1;
|
||||||
while r>=l do begin
|
while r>=l do begin
|
||||||
m:=(l+r) shr 1;
|
m:=(l+r) shr 1;
|
||||||
CurFilename:=@FListing.Names[FListing.NameStarts[m]];
|
CurFilename:=@Files[FListing.Starts[m]+NameOffset];
|
||||||
cmp:=ComparePCharUnitNameWithFilename(Pointer(AUnitName),CurFilename);
|
cmp:=ComparePCharUnitNameWithFilename(Pointer(AUnitName),CurFilename);
|
||||||
if cmp>0 then
|
if cmp>0 then
|
||||||
l:=m+1
|
l:=m+1
|
||||||
@ -847,12 +872,12 @@ begin
|
|||||||
// go to the first filename with the right unit name
|
// go to the first filename with the right unit name
|
||||||
while (m>0)
|
while (m>0)
|
||||||
and (ComparePCharUnitNameWithFilename(Pointer(AUnitName),
|
and (ComparePCharUnitNameWithFilename(Pointer(AUnitName),
|
||||||
@FListing.Names[FListing.NameStarts[m-1]])=0)
|
@Files[FListing.Starts[m-1]+NameOffset])=0)
|
||||||
do
|
do
|
||||||
dec(m);
|
dec(m);
|
||||||
// -> now find a filename with correct case and extension
|
// -> now find a filename with correct case and extension
|
||||||
while m<FListing.NameCount do begin
|
while m<FListing.Count do begin
|
||||||
CurFilename:=@FListing.Names[FListing.NameStarts[m]];
|
CurFilename:=@Files[FListing.Starts[m]+NameOffset];
|
||||||
// check if filename has the right AUnitName
|
// check if filename has the right AUnitName
|
||||||
if (ComparePCharUnitNameWithFilename(Pointer(AUnitName),CurFilename)<>0)
|
if (ComparePCharUnitNameWithFilename(Pointer(AUnitName),CurFilename)<>0)
|
||||||
then
|
then
|
||||||
@ -1115,9 +1140,9 @@ var
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
Filename: PChar;
|
Filename: PChar;
|
||||||
begin
|
begin
|
||||||
writeln('TCTDirectoryCache.WriteListing Count=',FListing.NameCount,' TextLen=',FListing.NamesLength);
|
writeln('TCTDirectoryCache.WriteListing Count=',FListing.Count,' Size=',FListing.Size);
|
||||||
for i:=0 to FListing.NameCount-1 do begin
|
for i:=0 to FListing.Count-1 do begin
|
||||||
Filename:=@FListing.Names[FListing.NameStarts[i]];
|
Filename:=@FListing.Files[FListing.Starts[i]+SizeOf(TCTDirectoryListingTime)];
|
||||||
writeln(i,' "',Filename,'"');
|
writeln(i,' "',Filename,'"');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1432,20 +1457,34 @@ end;
|
|||||||
|
|
||||||
procedure TCTDirectoryListing.Clear;
|
procedure TCTDirectoryListing.Clear;
|
||||||
begin
|
begin
|
||||||
if NameStarts<>nil then begin
|
if Starts<>nil then begin
|
||||||
FreeMem(NameStarts);
|
FreeMem(Starts);
|
||||||
NameStarts:=nil;
|
Starts:=nil;
|
||||||
NamesLength:=0;
|
Size:=0;
|
||||||
FreeMem(Names);
|
FreeMem(Files);
|
||||||
Names:=nil;
|
Files:=nil;
|
||||||
NameCount:=0;
|
Count:=0;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCTDirectoryListing.CalcMemSize: PtrUInt;
|
function TCTDirectoryListing.CalcMemSize: PtrUInt;
|
||||||
begin
|
begin
|
||||||
Result:=PtrUInt(InstanceSize)
|
Result:=PtrUInt(InstanceSize)
|
||||||
+PtrUInt(NamesLength);
|
+SizeOf(Pointer)*Count // Starts
|
||||||
|
+PtrUInt(Size); // Files
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryListing.GetFilename(Index: integer): PChar;
|
||||||
|
|
||||||
|
procedure RaiseIndexOutOfBounds;
|
||||||
|
begin
|
||||||
|
raise Exception.Create('TCTDirectoryListing.GetFilename: Index out of bounds');
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Index<0) or (Index>=Count) then
|
||||||
|
RaiseIndexOutOfBounds;
|
||||||
|
Result:=@Files[Starts[Index]+SizeOf(TCTDirectoryListingTime)];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TUnitFileNameLink }
|
{ TUnitFileNameLink }
|
||||||
|
@ -236,8 +236,8 @@ begin
|
|||||||
// search in directory for all files that could be sources or ppu files of this unit
|
// search in directory for all files that could be sources or ppu files of this unit
|
||||||
DirCache:=CodeToolBoss.DirectoryCachePool.GetCache(Dir,true,false);
|
DirCache:=CodeToolBoss.DirectoryCachePool.GetCache(Dir,true,false);
|
||||||
if (DirCache=nil) or (DirCache.Listing=nil) then exit;
|
if (DirCache=nil) or (DirCache.Listing=nil) then exit;
|
||||||
for i:=0 to DirCache.Listing.NameCount-1 do begin
|
for i:=0 to DirCache.Listing.Count-1 do begin
|
||||||
Filename:=PChar(@DirCache.Listing.Names[DirCache.Listing.NameStarts[i]]);
|
Filename:=DirCache.Listing.GetFilename(i);
|
||||||
Ext:=lowercase(ExtractFileExt(Filename));
|
Ext:=lowercase(ExtractFileExt(Filename));
|
||||||
if ((Ext='.pas') or (Ext='.pp') or (Ext='.p') or (Ext='.ppu'))
|
if ((Ext='.pas') or (Ext='.pp') or (Ext='.p') or (Ext='.ppu'))
|
||||||
and (SysUtils.CompareText(anUnitName,ExtractFileNameOnly(Filename))=0)
|
and (SysUtils.CompareText(anUnitName,ExtractFileNameOnly(Filename))=0)
|
||||||
|
Loading…
Reference in New Issue
Block a user