mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 01:11:07 +02:00
codetools: directorycacher: cache attr and size
git-svn-id: trunk@30988 -
This commit is contained in:
parent
ced61b53b4
commit
58a979dfaf
@ -105,13 +105,24 @@ type
|
|||||||
|
|
||||||
TCTDirectoryListingTime = longint;
|
TCTDirectoryListingTime = longint;
|
||||||
PCTDirectoryListingTime = ^TCTDirectoryListingTime;
|
PCTDirectoryListingTime = ^TCTDirectoryListingTime;
|
||||||
|
TCTDirectoryListingAttr = longint;
|
||||||
|
PCTDirectoryListingAttr = ^TCTDirectoryListingAttr;
|
||||||
|
TCTDirectoryListingSize = int64;
|
||||||
|
PCTDirectoryListingSize = ^TCTDirectoryListingSize;
|
||||||
|
|
||||||
|
TCTDirectoryListingHeader = packed record
|
||||||
|
Time: TCTDirectoryListingTime;
|
||||||
|
Attr: TCTDirectoryListingAttr;
|
||||||
|
Size: TCTDirectoryListingSize;
|
||||||
|
end;
|
||||||
|
PCTDirectoryListingHeader = ^TCTDirectoryListingHeader;
|
||||||
|
|
||||||
{ TCTDirectoryListing }
|
{ TCTDirectoryListing }
|
||||||
|
|
||||||
TCTDirectoryListing = class
|
TCTDirectoryListing = class
|
||||||
public
|
public
|
||||||
FileTimeStamp: integer;
|
FileTimeStamp: integer;
|
||||||
Files: PChar; { all filenames: each: time:TCTDirectoryListingTime+filename+#0
|
Files: PChar; { all filenames: each: time:TCTDirectoryListingHeader+filename+#0
|
||||||
sorted: first case insensitive then sensitive }
|
sorted: first case insensitive then sensitive }
|
||||||
Count: integer; // number of filenames
|
Count: integer; // number of filenames
|
||||||
Size: PtrInt; // length of Names in bytes
|
Size: PtrInt; // length of Names in bytes
|
||||||
@ -121,6 +132,8 @@ type
|
|||||||
function CalcMemSize: PtrUInt;
|
function CalcMemSize: PtrUInt;
|
||||||
function GetFilename(Index: integer): PChar;
|
function GetFilename(Index: integer): PChar;
|
||||||
function GetTime(Index: integer): TCTDirectoryListingTime;
|
function GetTime(Index: integer): TCTDirectoryListingTime;
|
||||||
|
function GetAttr(Index: integer): TCTDirectoryListingAttr;
|
||||||
|
function GetSize(Index: integer): TCTDirectoryListingSize;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TCTOnIterateFile = procedure(const Filename: string) of object;
|
TCTOnIterateFile = procedure(const Filename: string) of object;
|
||||||
@ -162,6 +175,8 @@ type
|
|||||||
function FindFile(const ShortFilename: string;
|
function FindFile(const ShortFilename: string;
|
||||||
const FileCase: TCTSearchFileCase): string;
|
const FileCase: TCTSearchFileCase): string;
|
||||||
function FileAge(const ShortFilename: string): TCTDirectoryListingTime;
|
function FileAge(const ShortFilename: string): TCTDirectoryListingTime;
|
||||||
|
function FileAttr(const ShortFilename: string): TCTDirectoryListingAttr;
|
||||||
|
function FileSize(const ShortFilename: string): TCTDirectoryListingSize;
|
||||||
function FindUnitSource(const AUnitName: string; AnyCase: boolean): string;
|
function FindUnitSource(const AUnitName: string; AnyCase: boolean): string;
|
||||||
function FindUnitSourceInCleanSearchPath(const AUnitName,
|
function FindUnitSourceInCleanSearchPath(const AUnitName,
|
||||||
SearchPath: string; AnyCase: boolean): string;
|
SearchPath: string; AnyCase: boolean): string;
|
||||||
@ -219,6 +234,8 @@ type
|
|||||||
procedure IncreaseConfigTimeStamp; inline;
|
procedure IncreaseConfigTimeStamp; inline;
|
||||||
function FileExists(Filename: string): boolean;
|
function FileExists(Filename: string): boolean;
|
||||||
function FileAge(Filename: string): TCTDirectoryListingTime;
|
function FileAge(Filename: string): TCTDirectoryListingTime;
|
||||||
|
function FileAttr(Filename: string): TCTDirectoryListingAttr;
|
||||||
|
function FileSize(Filename: string): TCTDirectoryListingSize;
|
||||||
function FindUnitInUnitLinks(const Directory, AUnitName: string): string;
|
function FindUnitInUnitLinks(const Directory, AUnitName: string): string;
|
||||||
function FindUnitInUnitSet(const Directory, AUnitName: string): string;
|
function FindUnitInUnitSet(const Directory, AUnitName: string): string;
|
||||||
function FindCompiledUnitInUnitSet(const Directory, AUnitName: string): string;
|
function FindCompiledUnitInUnitSet(const Directory, AUnitName: string): string;
|
||||||
@ -268,10 +285,12 @@ function CompareUnitNameWithUnitLinkNode(AUnitName: Pointer;
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
const
|
||||||
|
NameOffset = SizeOf(TCTDirectoryListingHeader);
|
||||||
type
|
type
|
||||||
TWorkFileInfo = record
|
TWorkFileInfo = record
|
||||||
|
Header: TCTDirectoryListingHeader;
|
||||||
FileName: string;
|
FileName: string;
|
||||||
Time: TCTDirectoryListingTime;
|
|
||||||
end;
|
end;
|
||||||
PWorkFileInfo = ^TWorkFileInfo;
|
PWorkFileInfo = ^TWorkFileInfo;
|
||||||
PPWorkFileInfo = ^PWorkFileInfo;
|
PPWorkFileInfo = ^PWorkFileInfo;
|
||||||
@ -562,14 +581,16 @@ begin
|
|||||||
if WorkingListingCapacity>0 then
|
if WorkingListingCapacity>0 then
|
||||||
NewCapacity:=WorkingListingCapacity*2
|
NewCapacity:=WorkingListingCapacity*2
|
||||||
else
|
else
|
||||||
NewCapacity:=8;
|
NewCapacity:=64;
|
||||||
ReAllocMem(WorkingListing,SizeOf(TWorkFileInfo)*NewCapacity);
|
ReAllocMem(WorkingListing,SizeOf(TWorkFileInfo)*NewCapacity);
|
||||||
FillChar(WorkingListing[WorkingListingCount],
|
FillChar(WorkingListing[WorkingListingCount],
|
||||||
SizeOf(TWorkFileInfo)*(NewCapacity-WorkingListingCapacity),0);
|
SizeOf(TWorkFileInfo)*(NewCapacity-WorkingListingCapacity),0);
|
||||||
WorkingListingCapacity:=NewCapacity;
|
WorkingListingCapacity:=NewCapacity;
|
||||||
end;
|
end;
|
||||||
WorkingItem:=@WorkingListing[WorkingListingCount];
|
WorkingItem:=@WorkingListing[WorkingListingCount];
|
||||||
WorkingItem^.Time:=FileInfo.Time;
|
WorkingItem^.Header.Time:=FileInfo.Time;
|
||||||
|
WorkingItem^.Header.Attr:=FileInfo.Attr;
|
||||||
|
WorkingItem^.Header.Size:=FileInfo.Size;
|
||||||
WorkingItem^.FileName:=FileInfo.Name;
|
WorkingItem^.FileName:=FileInfo.Name;
|
||||||
inc(WorkingListingCount);
|
inc(WorkingListingCount);
|
||||||
until FindNextUTF8(FileInfo)<>0;
|
until FindNextUTF8(FileInfo)<>0;
|
||||||
@ -587,7 +608,7 @@ 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].FileName)+1+SizeOf(TCTDirectoryListingTime));
|
inc(TotalLen,length(WorkingListing[i].FileName)+1+SizeOf(TCTDirectoryListingHeader));
|
||||||
GetMem(FListing.Files,TotalLen);
|
GetMem(FListing.Files,TotalLen);
|
||||||
FListing.Size:=TotalLen;
|
FListing.Size:=TotalLen;
|
||||||
FListing.Count:=WorkingListingCount;
|
FListing.Count:=WorkingListingCount;
|
||||||
@ -596,9 +617,8 @@ begin
|
|||||||
for i:=0 to WorkingListingCount-1 do begin
|
for i:=0 to WorkingListingCount-1 do begin
|
||||||
FListing.Starts[i]:=p-FListing.Files;
|
FListing.Starts[i]:=p-FListing.Files;
|
||||||
WorkingItem:=SortMap[i];
|
WorkingItem:=SortMap[i];
|
||||||
// time
|
PCTDirectoryListingHeader(p)^:=WorkingItem^.Header;
|
||||||
PCTDirectoryListingTime(p)^:=WorkingItem^.Time;
|
inc(p,SizeOf(TCTDirectoryListingHeader));
|
||||||
inc(p,SizeOf(TCTDirectoryListingTime));
|
|
||||||
// filename
|
// filename
|
||||||
CurFilenameLen:=length(WorkingItem^.FileName);
|
CurFilenameLen:=length(WorkingItem^.FileName);
|
||||||
if CurFilenameLen>0 then begin
|
if CurFilenameLen>0 then begin
|
||||||
@ -758,7 +778,7 @@ begin
|
|||||||
r:=FListing.Count-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:=@Files[FListing.Starts[m]+SizeOf(TCTDirectoryListingTime)];
|
CurFilename:=@Files[FListing.Starts[m]+NameOffset];
|
||||||
cmp:=ComparePCharCaseInsensitive(ShortFilename,CurFilename);// pointer type cast avoids #0 check
|
cmp:=ComparePCharCaseInsensitive(ShortFilename,CurFilename);// pointer type cast avoids #0 check
|
||||||
if cmp>0 then
|
if cmp>0 then
|
||||||
l:=m+1
|
l:=m+1
|
||||||
@ -789,7 +809,7 @@ begin
|
|||||||
r:=FListing.Count-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:=@Files[FListing.Starts[m]+SizeOf(TCTDirectoryListingTime)];
|
CurFilename:=@Files[FListing.Starts[m]+NameOffset];
|
||||||
cmp:=ComparePCharFirstCaseInsThenCase(ShortFilename,CurFilename);// pointer type cast avoids #0 check
|
cmp:=ComparePCharFirstCaseInsThenCase(ShortFilename,CurFilename);// pointer type cast avoids #0 check
|
||||||
if cmp>0 then
|
if cmp>0 then
|
||||||
l:=m+1
|
l:=m+1
|
||||||
@ -920,10 +940,48 @@ begin
|
|||||||
Result:=FListing.GetTime(i);
|
Result:=FListing.GetTime(i);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryCache.FileAttr(const ShortFilename: string
|
||||||
|
): TCTDirectoryListingAttr;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
if ShortFilename='' then exit;
|
||||||
|
if Directory='' then begin
|
||||||
|
// this is a virtual directory
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
{$IFDEF CaseInsensitiveFilenames}
|
||||||
|
i:=IndexOfFileCaseInsensitive(Pointer(ShortFilename));// pointer type cast avoids #0 check
|
||||||
|
{$ELSE}
|
||||||
|
i:=IndexOfFileCaseSensitive(Pointer(ShortFilename));
|
||||||
|
{$ENDIF}
|
||||||
|
if i>=0 then
|
||||||
|
Result:=FListing.GetAttr(i);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryCache.FileSize(const ShortFilename: string
|
||||||
|
): TCTDirectoryListingSize;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result:=-1;
|
||||||
|
if ShortFilename='' then exit;
|
||||||
|
if Directory='' then begin
|
||||||
|
// this is a virtual directory
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
{$IFDEF CaseInsensitiveFilenames}
|
||||||
|
i:=IndexOfFileCaseInsensitive(Pointer(ShortFilename));// pointer type cast avoids #0 check
|
||||||
|
{$ELSE}
|
||||||
|
i:=IndexOfFileCaseSensitive(Pointer(ShortFilename));
|
||||||
|
{$ENDIF}
|
||||||
|
if i>=0 then
|
||||||
|
Result:=FListing.GetSize(i);
|
||||||
|
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;
|
||||||
@ -1234,7 +1292,7 @@ var
|
|||||||
begin
|
begin
|
||||||
writeln('TCTDirectoryCache.WriteListing Count=',FListing.Count,' Size=',FListing.Size);
|
writeln('TCTDirectoryCache.WriteListing Count=',FListing.Count,' Size=',FListing.Size);
|
||||||
for i:=0 to FListing.Count-1 do begin
|
for i:=0 to FListing.Count-1 do begin
|
||||||
Filename:=@FListing.Files[FListing.Starts[i]+SizeOf(TCTDirectoryListingTime)];
|
Filename:=@FListing.Files[FListing.Starts[i]+NameOffset];
|
||||||
writeln(i,' "',Filename,'"');
|
writeln(i,' "',Filename,'"');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1255,7 +1313,7 @@ begin
|
|||||||
UpdateListing;
|
UpdateListing;
|
||||||
ListedFiles:=FListing.Files;
|
ListedFiles:=FListing.Files;
|
||||||
for i:=0 to FListing.Count-1 do
|
for i:=0 to FListing.Count-1 do
|
||||||
Files.Add(PChar(@ListedFiles[FListing.Starts[i]+SizeOf(TCTDirectoryListingTime)]));
|
Files.Add(PChar(@ListedFiles[FListing.Starts[i]+NameOffset]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCTDirectoryCachePool }
|
{ TCTDirectoryCachePool }
|
||||||
@ -1413,6 +1471,50 @@ begin
|
|||||||
Result:=FileStateCache.FileAgeCached(Filename);
|
Result:=FileStateCache.FileAgeCached(Filename);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryCachePool.FileAttr(Filename: string
|
||||||
|
): TCTDirectoryListingAttr;
|
||||||
|
var
|
||||||
|
Directory: String;
|
||||||
|
Cache: TCTDirectoryCache;
|
||||||
|
ShortFilename: String;
|
||||||
|
begin
|
||||||
|
Filename:=TrimFilename(Filename);
|
||||||
|
if (Filename<>'') and FilenameIsAbsolute(Filename) then begin
|
||||||
|
ShortFilename:=ExtractFilename(Filename);
|
||||||
|
if (ShortFilename<>'') and (ShortFilename<>'.') and (ShortFilename<>'..')
|
||||||
|
then begin
|
||||||
|
Directory:=ExtractFilePath(Filename);
|
||||||
|
Cache:=GetCache(Directory,true,false);
|
||||||
|
Result:=Cache.FileAttr(ShortFilename);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// fallback
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryCachePool.FileSize(Filename: string
|
||||||
|
): TCTDirectoryListingSize;
|
||||||
|
var
|
||||||
|
Directory: String;
|
||||||
|
Cache: TCTDirectoryCache;
|
||||||
|
ShortFilename: String;
|
||||||
|
begin
|
||||||
|
Filename:=TrimFilename(Filename);
|
||||||
|
if (Filename<>'') and FilenameIsAbsolute(Filename) then begin
|
||||||
|
ShortFilename:=ExtractFilename(Filename);
|
||||||
|
if (ShortFilename<>'') and (ShortFilename<>'.') and (ShortFilename<>'..')
|
||||||
|
then begin
|
||||||
|
Directory:=ExtractFilePath(Filename);
|
||||||
|
Cache:=GetCache(Directory,true,false);
|
||||||
|
Result:=Cache.FileSize(ShortFilename);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// fallback
|
||||||
|
Result:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCTDirectoryCachePool.FindUnitInUnitLinks(const Directory,
|
function TCTDirectoryCachePool.FindUnitInUnitLinks(const Directory,
|
||||||
AUnitName: string): string;
|
AUnitName: string): string;
|
||||||
|
|
||||||
@ -1645,20 +1747,46 @@ function TCTDirectoryListing.GetFilename(Index: integer): PChar;
|
|||||||
begin
|
begin
|
||||||
if (Index<0) or (Index>=Count) then
|
if (Index<0) or (Index>=Count) then
|
||||||
RaiseIndexOutOfBounds;
|
RaiseIndexOutOfBounds;
|
||||||
Result:=@Files[Starts[Index]+SizeOf(TCTDirectoryListingTime)];
|
Result:=@Files[Starts[Index]+NameOffset];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCTDirectoryListing.GetTime(Index: integer): TCTDirectoryListingTime;
|
function TCTDirectoryListing.GetTime(Index: integer): TCTDirectoryListingTime;
|
||||||
|
|
||||||
procedure RaiseIndexOutOfBounds;
|
procedure RaiseIndexOutOfBounds;
|
||||||
begin
|
begin
|
||||||
raise Exception.Create('TCTDirectoryListing.GetFilename: Index out of bounds');
|
raise Exception.Create('TCTDirectoryListing.GetTime: Index out of bounds');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (Index<0) or (Index>=Count) then
|
if (Index<0) or (Index>=Count) then
|
||||||
RaiseIndexOutOfBounds;
|
RaiseIndexOutOfBounds;
|
||||||
Result:=PCTDirectoryListingTime(@Files[Starts[Index]])^;
|
Result:=PCTDirectoryListingHeader(@Files[Starts[Index]])^.Time;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryListing.GetAttr(Index: integer): TCTDirectoryListingAttr;
|
||||||
|
|
||||||
|
procedure RaiseIndexOutOfBounds;
|
||||||
|
begin
|
||||||
|
raise Exception.Create('TCTDirectoryListing.GetAttr: Index out of bounds');
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Index<0) or (Index>=Count) then
|
||||||
|
RaiseIndexOutOfBounds;
|
||||||
|
Result:=PCTDirectoryListingHeader(@Files[Starts[Index]])^.Attr;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCTDirectoryListing.GetSize(Index: integer): TCTDirectoryListingSize;
|
||||||
|
|
||||||
|
procedure RaiseIndexOutOfBounds;
|
||||||
|
begin
|
||||||
|
raise Exception.Create('TCTDirectoryListing.GetSize: Index out of bounds');
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Index<0) or (Index>=Count) then
|
||||||
|
RaiseIndexOutOfBounds;
|
||||||
|
Result:=PCTDirectoryListingHeader(@Files[Starts[Index]])^.Size;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TUnitFileNameLink }
|
{ TUnitFileNameLink }
|
||||||
|
Loading…
Reference in New Issue
Block a user