with Ada.Strings.Unbounded.Text_IO, Ada.Text_IO, CSV; use Ada.Strings.Unbounded.Text_IO, Ada.Text_IO; package body Bundles.Containers is package My_CSV is new CSV; package SU renames Ada.Strings.Unbounded; protected type Preference_Input is procedure Open (Filename : in String); procedure Read_Line (Line : out SU.Unbounded_String; EOF : out Boolean); procedure Close; private Source : File_Type; end Preference_Input; protected body Preference_Input is procedure Open (Filename : in String) is begin Open (Source, In_File, Filename); end Open; procedure Read_Line (Line : out SU.Unbounded_String; EOF : out Boolean) is begin if End_Of_File (Source) then EOF := True; else EOF := False; Line := Get_Line (Source); end if; end Read_Line; procedure Close is begin Ada.Text_IO.Close (Source); end Close; end Preference_Input; type Paper_Array is array (Valid_CandidateID) of Paper_Vectors.Vector; type Paper_Array_Array is array (1 .. Num_Threads) of Paper_Array; Empty_Paper_Array : Paper_Array := (others => Paper_Vectors.Empty_Vector); task type Parse_Worker (Input : access Preference_Input; Output : access Paper_Array_Array) is entry Start (On : in Positive); end Parse_Worker; task body Parse_Worker is use type Candidates.CandidateID; Work_On : Positive; Current_Line : SU.Unbounded_String; Current_Record : My_CSV.CSV_Record; Current_Prefs : Given_Prefs.Preference_Array; Are_We_Done_Yet : Boolean; begin accept Start (On : in Positive) do Work_On := On; end Start; loop Input.Read_Line (Current_Line, Are_We_Done_Yet); exit when Are_We_Done_Yet; Current_Record := My_CSV.Parse_Line (SU.To_String (Current_Line)); if Integer (Current_Record.Length) > 0 then Current_Prefs := Given_Prefs.Parse_Preferences (SU.To_String (Current_Record.Last_Element)); if Current_Prefs (Given_Prefs.Preference_Range'First) /= Candidates.No_Candidate then Output (Work_On) (Current_Prefs (Given_Prefs.Preference_Range'First)).Append (Current_Prefs); end if; end if; end loop; end Parse_Worker; procedure Read_Bundles_Threaded (Filename : in String; Result : out Bundle_Collection) is use type Bundle_Vector; Input : aliased Preference_Input; Outputs : aliased Paper_Array_Array := (others => Empty_Paper_Array); begin Result := (others => Bundle_Vectors.Empty_Vector & Empty_Bundle); Input.Open (Filename); declare Workers : array (1 .. Num_Threads) of Parse_Worker (Input'Access, Outputs'Access); begin for I in Workers'Range loop Workers (I).Start (I); end loop; end; Input.Close; for CID in Valid_CandidateID loop for O of Outputs loop Result (CID).Reference (1).Papers.Append (O (CID)); O (CID) := Paper_Vectors.Empty_Vector; end loop; if Result (CID).Reference (1) = Empty_Bundle then Result (CID).Delete (1); end if; end loop; end Read_Bundles_Threaded; procedure Read_Bundles (Filename : in String; Result : out Bundle_Collection) is package My_CSV is new CSV; use Ada.Text_IO; use type Candidates.CandidateID; use type Bundle_Vectors.Vector; Input_File : File_Type; Current_Record : My_CSV.CSV_Record; Current_Prefs : Given_Prefs.Preference_Array; begin Result := (others => Bundle_Vectors.Empty_Vector & Empty_Bundle); Open (Input_File, In_File, Filename); while not End_Of_File (Input_File) loop Current_Record := My_CSV.Parse_Line (Get_Line (Input_File)); if Integer (Current_Record.Length) > 0 then Current_Prefs := Given_Prefs.Parse_Preferences (SU.To_String (Current_Record.Last_Element)); if Current_Prefs (Given_Prefs.Preference_Range'First) /= Candidates.No_Candidate then Result (Current_Prefs (Given_Prefs.Preference_Range'First)).Reference (1).Papers.Append (Current_Prefs); end if; end if; end loop; Close (Input_File); for B of Result loop if B.Reference (1) = Empty_Bundle then B.Delete (1); end if; end loop; end Read_Bundles; end Bundles.Containers;