Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -1,128 +0,0 @@
|
|||
with Ada.Command_Line;
|
||||
with Ada.Containers;
|
||||
with Ada.Containers.Ordered_Maps;
|
||||
with Ada.Containers.Indefinite_Vectors;
|
||||
with Ada.Directories;
|
||||
with Ada.Streams.Stream_IO;
|
||||
with Ada.Text_IO;
|
||||
|
||||
with GNAT.MD5;
|
||||
|
||||
procedure Find_Duplicates is
|
||||
|
||||
Root_Dir : constant String := Ada.Command_Line.Argument (1);
|
||||
Size_Limit : constant Ada.Directories.File_Size :=
|
||||
Ada.Directories.File_Size'Value (Ada.Command_Line.Argument (2));
|
||||
Pattern : constant String := "*";
|
||||
Filter : constant Ada.Directories.Filter_Type :=
|
||||
(
|
||||
Ada.Directories.Directory => True,
|
||||
Ada.Directories.Ordinary_File => True,
|
||||
others => False
|
||||
);
|
||||
|
||||
type File_Data is
|
||||
record
|
||||
Hash : GNAT.MD5.Message_Digest;
|
||||
Size : Ada.Directories.File_Size;
|
||||
end record;
|
||||
|
||||
type File_Name is new String;
|
||||
|
||||
function File_Order (Left, Right : File_Data) return Boolean is
|
||||
(Ada.Directories."<" (Right.Size, Left.Size));
|
||||
|
||||
package Dir_Vectors is new Ada.Containers.Indefinite_Vectors
|
||||
(Index_Type => Positive, Element_Type => File_Name);
|
||||
package Dir_Maps is new Ada.Containers.Ordered_Maps
|
||||
(Key_Type => File_Data, Element_Type => Dir_Vectors.Vector,
|
||||
"<" => File_Order, "=" => Dir_Vectors."=");
|
||||
|
||||
function File_Hash (Name : String) return GNAT.MD5.Message_Digest is
|
||||
File : Ada.Streams.Stream_IO.File_Type;
|
||||
Context : GNAT.MD5.Context := GNAT.MD5.Initial_Context;
|
||||
Items : Ada.Streams.Stream_Element_Array
|
||||
(1 .. 4096);
|
||||
Last : Ada.Streams.Stream_Element_Offset := 0;
|
||||
begin
|
||||
Ada.Streams.Stream_IO.Open (File, Ada.Streams.Stream_IO.In_File, Name);
|
||||
|
||||
while not Ada.Streams.Stream_IO.End_Of_File (File) loop
|
||||
Ada.Streams.Stream_IO.Read (File, Items, Last);
|
||||
|
||||
if Ada.Streams."<" (Last, Items'Last) then
|
||||
GNAT.MD5.Update (Context, Items (Items'First .. Last));
|
||||
else
|
||||
GNAT.MD5.Update (Context, Items);
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return GNAT.MD5.Digest (Context);
|
||||
end;
|
||||
|
||||
Dir_Map : Dir_Maps.Map := Dir_Maps.Empty_Map;
|
||||
|
||||
procedure Insert (Name : String) is
|
||||
Hash : constant GNAT.MD5.Message_Digest := File_Hash (Name);
|
||||
Size : constant Ada.Directories.File_Size := Ada.Directories.Size (Name);
|
||||
Data : constant File_Data := (Hash, Size);
|
||||
Pos : Dir_Maps.Cursor;
|
||||
Ins : Boolean;
|
||||
procedure Append_Name (K : File_Data; V : in out Dir_Vectors.Vector) is
|
||||
begin
|
||||
V.Append (File_Name (Name));
|
||||
end Append_Name;
|
||||
begin
|
||||
Dir_Map.Insert (Data, Dir_Vectors.Empty_Vector, Pos, Ins);
|
||||
-- We can update whether we inserted a new element or not.
|
||||
Dir_Map.Update_Element (Pos, Append_Name'Access);
|
||||
end Insert;
|
||||
|
||||
procedure Walk (Dir_Ent : Ada.Directories.Directory_Entry_Type) is
|
||||
Name : constant String := Ada.Directories.Full_Name (Dir_Ent);
|
||||
SName : constant String := Ada.Directories.Simple_Name (Dir_Ent);
|
||||
Size : Ada.Directories.File_Size;
|
||||
begin
|
||||
if SName = "." or else SName = ".." then
|
||||
return;
|
||||
end if;
|
||||
|
||||
case Ada.Directories.Kind (Dir_Ent) is
|
||||
when Ada.Directories.Ordinary_File =>
|
||||
Size := Ada.Directories.Size (Name);
|
||||
if Ada.Directories.">=" (Size, Size_Limit) then
|
||||
Insert (Name);
|
||||
end if;
|
||||
when Ada.Directories.Directory =>
|
||||
Ada.Directories.Search
|
||||
(Name, Pattern, Filter, Walk'Access);
|
||||
when others => raise Constraint_Error;
|
||||
end case;
|
||||
end Walk;
|
||||
|
||||
procedure Show_Duplicates is
|
||||
Count : Ada.Containers.Count_Type;
|
||||
K : File_Data;
|
||||
Dv : Dir_Vectors.Vector;
|
||||
begin
|
||||
for Pos in Dir_Map.Iterate loop
|
||||
Dv := Dir_Map.Constant_Reference (Pos);
|
||||
Count := Dv.Length;
|
||||
|
||||
if Ada.Containers.">"(Count, 1) then
|
||||
K := Dir_Maps.Key (Pos);
|
||||
Ada.Text_IO.Put_Line
|
||||
("Found " & Count'Image & " files matching Size => "
|
||||
& K.Size'Image & ", MD5 => " & K.Hash);
|
||||
|
||||
for E of Dv loop
|
||||
Ada.Text_IO.Put_Line (String (E));
|
||||
end loop;
|
||||
end if;
|
||||
end loop;
|
||||
end Show_Duplicates;
|
||||
begin
|
||||
Ada.Directories.Search
|
||||
(Root_Dir, Pattern, Filter, Walk'Access);
|
||||
Show_Duplicates;
|
||||
end Find_Duplicates;
|
||||
Loading…
Add table
Add a link
Reference in a new issue