implemented sorting installed packages topologically

git-svn-id: trunk@6296 -
This commit is contained in:
mattias 2004-11-25 22:05:01 +00:00
parent 7bdefae9f7
commit 488aa4bca8
6 changed files with 201 additions and 11 deletions

View File

@ -34,7 +34,7 @@ unit CGILazIDEIntf;
interface interface
uses uses
Classes, SysUtils, cgiApp, cgiModules, LazIDEIntf, ProjectIntf, NewItemIntf; Classes, SysUtils, cgiApp, cgiModules, LazIDEIntf, ProjectIntf;
type type
{ TCGIApplicationDescriptor } { TCGIApplicationDescriptor }

View File

@ -325,8 +325,6 @@ begin
end; end;
procedure TCustomGTKGLAreaControl.UpdateFrameTimeDiff; procedure TCustomGTKGLAreaControl.UpdateFrameTimeDiff;
var
hour, minutes, secs, msecs, usecs: word;
begin begin
FCurrentFrameTime:=GetTickCount; FCurrentFrameTime:=GetTickCount;
if FLastFrameTime=0 then if FLastFrameTime=0 then

View File

@ -2012,7 +2012,7 @@ var
ASrcEdit: TSourceEditor; ASrcEdit: TSourceEditor;
AnUnitInfo: TUnitInfo; AnUnitInfo: TUnitInfo;
begin begin
debugln('TDebugManager.OnProcessIDECommand ',dbgs(Command)); //debugln('TMainIDE.OnProcessIDECommand ',dbgs(Command));
Handled:=true; Handled:=true;
@ -10965,6 +10965,9 @@ end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.799 2004/11/25 22:05:00 mattias
implemented sorting installed packages topologically
Revision 1.798 2004/11/24 08:18:13 mattias Revision 1.798 2004/11/24 08:18:13 mattias
TTextStrings improvements (Exchange, Put), clean ups TTextStrings improvements (Exchange, Put), clean ups

View File

@ -216,6 +216,12 @@ type
); );
TPkgDependencyFlags = set of TPkgDependencyFlag; TPkgDependencyFlags = set of TPkgDependencyFlag;
TPkgMarkerFlag = (
pmfVisited,
pmfMarked
);
TPkgMarkerFlags = set of TPkgMarkerFlag;
TLoadPackageResult = ( TLoadPackageResult = (
lprUndefined, lprUndefined,
lprSuccess, lprSuccess,
@ -233,6 +239,7 @@ type
FFlags: TPkgDependencyFlags; FFlags: TPkgDependencyFlags;
FHoldPackage: boolean; FHoldPackage: boolean;
FLoadPackageResult: TLoadPackageResult; FLoadPackageResult: TLoadPackageResult;
FMarkerFlags: TPKgMarkerFlags;
FOwner: TObject; FOwner: TObject;
FMaxVersion: TPkgVersion; FMaxVersion: TPkgVersion;
FMinVersion: TPkgVersion; FMinVersion: TPkgVersion;
@ -287,6 +294,7 @@ type
property RequiredPackage: TLazPackage read FRequiredPackage write SetRequiredPackage; property RequiredPackage: TLazPackage read FRequiredPackage write SetRequiredPackage;
property LoadPackageResult: TLoadPackageResult read FLoadPackageResult write SetLoadPackageResult; property LoadPackageResult: TLoadPackageResult read FLoadPackageResult write SetLoadPackageResult;
property HoldPackage: boolean read FHoldPackage write SetHoldPackage; property HoldPackage: boolean read FHoldPackage write SetHoldPackage;
property MarkerFlags: TPKgMarkerFlags read FMarkerFlags write FMarkerFlags;
end; end;
PPkgDependency = ^TPkgDependency; PPkgDependency = ^TPkgDependency;
@ -550,6 +558,7 @@ type
FRegistered: boolean; FRegistered: boolean;
FSourceDirectories: TFileReferenceList; FSourceDirectories: TFileReferenceList;
FStateFileDate: longint; FStateFileDate: longint;
FTopologicalLevel: integer;
FUpdateLock: integer; FUpdateLock: integer;
FUsageOptions: TPkgAdditionalCompilerOptions; FUsageOptions: TPkgAdditionalCompilerOptions;
FUserReadOnly: boolean; FUserReadOnly: boolean;
@ -721,6 +730,7 @@ type
property RemovedFiles[Index: integer]: TPkgFile read GetRemovedFiles; property RemovedFiles[Index: integer]: TPkgFile read GetRemovedFiles;
property SourceDirectories: TFileReferenceList read FSourceDirectories; property SourceDirectories: TFileReferenceList read FSourceDirectories;
property StateFileDate: longint read FStateFileDate write FStateFileDate; property StateFileDate: longint read FStateFileDate write FStateFileDate;
property TopologicalLevel: integer read FTopologicalLevel write FTopologicalLevel;
property UsageOptions: TPkgAdditionalCompilerOptions read FUsageOptions; property UsageOptions: TPkgAdditionalCompilerOptions read FUsageOptions;
property UserReadOnly: boolean read FUserReadOnly write SetUserReadOnly; property UserReadOnly: boolean read FUserReadOnly write SetUserReadOnly;
end; end;

View File

@ -179,6 +179,9 @@ type
Policies: TPackageUpdatePolicies): TList; Policies: TPackageUpdatePolicies): TList;
function GetBrokenDependenciesWhenChangingPkgID(APackage: TLazPackage; function GetBrokenDependenciesWhenChangingPkgID(APackage: TLazPackage;
const NewName: string; NewVersion: TPkgVersion): TList; const NewName: string; NewVersion: TPkgVersion): TList;
procedure CalculateTopologicalLevels;
procedure SortDependencyListTopologically(
var FirstDependency: TPkgDependency; TopLevelFirst: boolean);
procedure IterateAllComponentClasses(Event: TIterateComponentClassesEvent); procedure IterateAllComponentClasses(Event: TIterateComponentClassesEvent);
procedure IterateComponentClasses(APackage: TLazPackage; procedure IterateComponentClasses(APackage: TLazPackage;
Event: TIterateComponentClassesEvent; Event: TIterateComponentClassesEvent;
@ -188,6 +191,8 @@ type
procedure IteratePackagesSorted(Flags: TFindPackageFlags; procedure IteratePackagesSorted(Flags: TFindPackageFlags;
Event: TIteratePackagesEvent); Event: TIteratePackagesEvent);
procedure MarkAllPackagesAsNotVisited; procedure MarkAllPackagesAsNotVisited;
procedure MarkAllDependencies(MarkPackages: boolean;
AddMarkerFlags, RemoveMarkerFlags: TPkgMarkerFlags);
procedure MarkAllRequiredPackages(FirstDependency: TPkgDependency); procedure MarkAllRequiredPackages(FirstDependency: TPkgDependency);
procedure MarkNeededPackages; procedure MarkNeededPackages;
procedure ConsistencyCheck; procedure ConsistencyCheck;
@ -1020,7 +1025,7 @@ begin
Filename:=SetDirSeparators('$(LazarusDir)/ideintf/'); Filename:=SetDirSeparators('$(LazarusDir)/ideintf/');
Version.SetValues(1,0,0,0); Version.SetValues(1,0,0,0);
Author:='Lazarus'; Author:='Lazarus';
License:='GPL-2'; License:='LGPL-2';
AutoInstall:=pitStatic; AutoInstall:=pitStatic;
AutoUpdate:=pupManually; AutoUpdate:=pupManually;
Description:='IDEIntf - the interface units for the IDE'; Description:='IDEIntf - the interface units for the IDE';
@ -1042,6 +1047,7 @@ begin
AddFile('idecommands.pas','IDECommands',pftUnit,[],cpBase); AddFile('idecommands.pas','IDECommands',pftUnit,[],cpBase);
AddFile('imagelisteditor.pp','ImageListEditor',pftUnit,[],cpBase); AddFile('imagelisteditor.pp','ImageListEditor',pftUnit,[],cpBase);
AddFile('listviewpropedit.pp','ListViewPropEdit',pftUnit,[],cpBase); AddFile('listviewpropedit.pp','ListViewPropEdit',pftUnit,[],cpBase);
AddFile('newitemintf.pas','NewItemIntf',pftUnit,[],cpBase);
AddFile('objectinspector.pp','ObjectInspector',pftUnit,[],cpBase); AddFile('objectinspector.pp','ObjectInspector',pftUnit,[],cpBase);
AddFile('objinspstrconsts.pas','ObjInspStrConsts',pftUnit,[],cpBase); AddFile('objinspstrconsts.pas','ObjInspStrConsts',pftUnit,[],cpBase);
AddFile('packageintf.pas','PackageIntf',pftUnit,[],cpBase); AddFile('packageintf.pas','PackageIntf',pftUnit,[],cpBase);
@ -1753,6 +1759,27 @@ begin
end; end;
end; end;
procedure TLazPackageGraph.MarkAllDependencies(
MarkPackages: boolean; AddMarkerFlags, RemoveMarkerFlags: TPkgMarkerFlags);
var
i: Integer;
Pkg: TLazPackage;
Dependency: TPkgDependency;
begin
// mark all dependencies of all packages as not visited
for i:=FItems.Count-1 downto 0 do begin
Pkg:=TLazPackage(FItems[i]);
if MarkPackages then
Pkg.Flags:=Pkg.Flags-[lpfVisited];
Dependency:=Pkg.FirstRequiredDependency;
while Dependency<>nil do begin
Dependency.MarkerFlags:=
Dependency.MarkerFlags+AddMarkerFlags-RemoveMarkerFlags;
Dependency:=Dependency.NextRequiresDependency;
end;
end;
end;
procedure TLazPackageGraph.MarkAllRequiredPackages( procedure TLazPackageGraph.MarkAllRequiredPackages(
FirstDependency: TPkgDependency); FirstDependency: TPkgDependency);
var var
@ -1850,11 +1877,153 @@ begin
end; end;
end; end;
procedure TLazPackageGraph.CalculateTopologicalLevels;
procedure GetTopologicalOrder(CurDependency: TPkgDependency;
var MaxChildLevel: integer);
var
RequiredPackage: TLazPackage;
CurMaxChildLevel: integer;
begin
MaxChildLevel:=0;
while CurDependency<>nil do begin
if CurDependency.LoadPackageResult=lprSuccess then begin
RequiredPackage:=CurDependency.RequiredPackage;
if (not (lpfVisited in RequiredPackage.Flags)) then begin
RequiredPackage.Flags:=RequiredPackage.Flags+[lpfVisited];
GetTopologicalOrder(RequiredPackage.FirstRequiredDependency,
CurMaxChildLevel);
RequiredPackage.TopologicalLevel:=CurMaxChildLevel+1;
end;
if RequiredPackage.TopologicalLevel>MaxChildLevel then
MaxChildLevel:=RequiredPackage.TopologicalLevel;
end;
CurDependency:=CurDependency.NextRequiresDependency;
end;
end;
var
i: Integer;
Pkg: TLazPackage;
CurMaxChildLevel: integer;
begin
for i:=FItems.Count-1 downto 0 do begin
Pkg:=TLazPackage(FItems[i]);
Pkg.Flags:=Pkg.Flags-[lpfVisited];
Pkg.TopologicalLevel:=0;
end;
for i:=FItems.Count-1 downto 0 do begin
Pkg:=TLazPackage(FItems[i]);
GetTopologicalOrder(Pkg.FirstRequiredDependency,CurMaxChildLevel);
Pkg.TopologicalLevel:=CurMaxChildLevel+1;
end;
end;
procedure TLazPackageGraph.SortDependencyListTopologically(
var FirstDependency: TPkgDependency; TopLevelFirst: boolean);
// Sort dependency list topologically.
// If TopLevelFirst is true then packages that needs others come first
var
Dependency: TPkgDependency;
BucketStarts: PInteger;
MaxLvl: Integer;
BucketCount: Integer;
DependencyCount: Integer;
Dependencies: PPkgDependency;
i: Integer;
j: Integer;
CurLvl: LongInt;
begin
CalculateTopologicalLevels;
// Bucket sort dependencies
MaxLvl:=0;
Dependency:=FirstDependency;
DependencyCount:=0;
while Dependency<>nil do begin
if Dependency.RequiredPackage<>nil then begin
if MaxLvl<Dependency.RequiredPackage.TopologicalLevel then
MaxLvl:=Dependency.RequiredPackage.TopologicalLevel;
end;
Dependency:=Dependency.NextRequiresDependency;
inc(DependencyCount);
end;
if (MaxLvl=0) or (DependencyCount<=1) then exit;
//debugln('TLazPackageGraph.SortDependencyListTopologically A MaxLvl=',dbgs(MaxLvl),' ',dbgs(DependencyCount));
// compute BucketStarts
BucketCount:=MaxLvl+1;
GetMem(BucketStarts,SizeOf(Integer)*BucketCount);
FillChar(BucketStarts^,SizeOf(Integer)*BucketCount,0);
Dependency:=FirstDependency;
while Dependency<>nil do begin
if Dependency.RequiredPackage<>nil then
CurLvl:=Dependency.RequiredPackage.TopologicalLevel
else
CurLvl:=0;
if CurLvl+1<BucketCount then
inc(BucketStarts[CurLvl+1]);
Dependency:=Dependency.NextRequiresDependency;
end;
for i:=2 to MaxLvl do
BucketStarts[i]:=BucketStarts[i]+BucketStarts[i-1];
BucketStarts[0]:=0;
// put Dependencies into buckets
GetMem(Dependencies,SizeOf(Pointer)*DependencyCount);
FillChar(Dependencies^,SizeOf(Pointer)*DependencyCount,0);
Dependency:=FirstDependency;
while Dependency<>nil do begin
if Dependency.RequiredPackage<>nil then
CurLvl:=Dependency.RequiredPackage.TopologicalLevel
else
CurLvl:=0;
//debugln('BBB1 BucketStarts[',dbgs(CurLvl),']=',dbgs(BucketStarts[CurLvl]),' ',Dependency.AsString);
if Dependencies[BucketStarts[CurLvl]]<>nil then
RaiseException('');
Dependencies[BucketStarts[CurLvl]]:=Dependency;
inc(BucketStarts[CurLvl]);
Dependency:=Dependency.NextRequiresDependency;
end;
// optional: reverse order
if TopLevelFirst then begin
i:=0;
j:=DependencyCount-1;
while (i<j) do begin
Dependency:=Dependencies[i];
Dependencies[i]:=Dependencies[j];
Dependencies[j]:=Dependency;
inc(i);
dec(j);
end;
end;
// commit order
FirstDependency:=Dependencies[0];
for i:=0 to DependencyCount-1 do begin
Dependency:=Dependencies[i];
//debugln('TLazPackageGraph.SortDependencyListTopologically A ',Dependency.AsString);
if i=0 then
Dependency.PrevDependency[pdlRequires]:=nil
else
Dependency.PrevDependency[pdlRequires]:=Dependencies[i-1];
if i=DependencyCount-1 then
Dependency.NextDependency[pdlRequires]:=nil
else
Dependency.NextDependency[pdlRequires]:=Dependencies[i+1];
end;
// clean up
FreeMem(BucketStarts);
FreeMem(Dependencies);
end;
function TLazPackageGraph.CheckIfPackageCanBeClosed(APackage: TLazPackage function TLazPackageGraph.CheckIfPackageCanBeClosed(APackage: TLazPackage
): boolean; ): boolean;
begin begin
MarkNeededPackages; MarkNeededPackages;
Result:=lpfNeeded in APackage.FLags; Result:=lpfNeeded in APackage.Flags;
end; end;
function TLazPackageGraph.PackageIsNeeded(APackage: TLazPackage): boolean; function TLazPackageGraph.PackageIsNeeded(APackage: TLazPackage): boolean;

View File

@ -162,6 +162,7 @@ type
procedure LoadStaticCustomPackages; procedure LoadStaticCustomPackages;
function LoadInstalledPackage(const PackageName: string): TLazPackage; function LoadInstalledPackage(const PackageName: string): TLazPackage;
procedure LoadAutoInstallPackages; procedure LoadAutoInstallPackages;
procedure SortAutoInstallDependencies;
public public
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -1434,8 +1435,6 @@ begin
MiscellaneousOptions.BuildLazOpts.WithStaticPackages:=true; MiscellaneousOptions.BuildLazOpts.WithStaticPackages:=true;
end; end;
// TODO: sort FirstAutoInstallDependency topological
sl:=TStringList.Create; sl:=TStringList.Create;
Dependency:=FirstAutoInstallDependency; Dependency:=FirstAutoInstallDependency;
while Dependency<>nil do begin while Dependency<>nil do begin
@ -1469,7 +1468,7 @@ begin
PackageGraph.OpenDependency(Dependency); PackageGraph.OpenDependency(Dependency);
Dependency.AddToList(FirstAutoInstallDependency,pdlRequires); Dependency.AddToList(FirstAutoInstallDependency,pdlRequires);
end; end;
// TODO: sort FirstAutoInstallDependency topological SortAutoInstallDependencies;
// register them // register them
PackageGraph.RegisterStaticBasePackages; PackageGraph.RegisterStaticBasePackages;
@ -1551,6 +1550,14 @@ begin
end; end;
Dependency.RequiredPackage.AutoInstall:=pitStatic; Dependency.RequiredPackage.AutoInstall:=pitStatic;
end; end;
SortAutoInstallDependencies;
end;
procedure TPkgManager.SortAutoInstallDependencies;
begin
// sort install dependencies, so that lower packages come first
PackageGraph.SortDependencyListTopologically(FirstAutoInstallDependency,
false);
end; end;
constructor TPkgManager.Create(TheOwner: TComponent); constructor TPkgManager.Create(TheOwner: TComponent);
@ -3087,9 +3094,10 @@ begin
NeedSaving:=true; NeedSaving:=true;
end; end;
end; end;
// TODO: sort FirstAutoInstallDependency topological if NeedSaving then begin
if NeedSaving then SortAutoInstallDependencies;
SaveAutoInstallDependencies(true); SaveAutoInstallDependencies(true);
end;
// save IDE build configs, so user can build IDE on command line // save IDE build configs, so user can build IDE on command line
BuildIDEFlags:=[blfWithStaticPackages,blfQuick,blfOnlyIDE]; BuildIDEFlags:=[blfWithStaticPackages,blfQuick,blfOnlyIDE];
@ -3160,6 +3168,7 @@ begin
if Dependency<>nil then begin if Dependency<>nil then begin
Dependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires); Dependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires);
Dependency.Free; Dependency.Free;
SortAutoInstallDependencies;
end; end;
SaveAutoInstallDependencies(true); SaveAutoInstallDependencies(true);
end; end;
@ -3215,6 +3224,7 @@ begin
if Result<>mrYes then exit; if Result<>mrYes then exit;
OldDependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires); OldDependency.RemoveFromList(FirstAutoInstallDependency,pdlRequires);
OldDependency.Free; OldDependency.Free;
SaveAutoInstallDependencies(true);
end; end;
end; end;