summaryrefslogtreecommitdiff
path: root/src/bundles-containers.adb
blob: 0550f6d9aa898e076a10dd15f06b87aa9f4cb23d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190


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;