File: test_htables.adb

package info (click to toggle)
gnat-gps 5.3dfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 50,360 kB
  • ctags: 11,617
  • sloc: ada: 374,346; ansic: 92,327; python: 15,979; xml: 12,186; sh: 3,277; makefile: 1,113; awk: 154; perl: 128; java: 17
file content (212 lines) | stat: -rw-r--r-- 6,045 bytes parent folder | download | duplicates (2)
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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
with HTables;
with String_Utils;
with Ada.Text_IO; use Ada.Text_IO;

procedure Test_HTables is

  Verbose : constant Boolean := False;

   --  Small regression test for the HTables package. This is not the prettiest
   --  code, but it does the job.

   --  Note: The implementation of Simple_HTable is based on the implementation
   --  of Static_HTable, so testing Simple_HTable only is enough to cover
   --  the entire HTables code.

   type Index is range 1 .. 1000;
   No_Element : constant Natural := Natural'First;
   type String_Access is access String;

   function Hash (F : String_Access) return Index;
   procedure Free (X : in out Natural);

   package SHT is new HTables.Simple_HTable
     (Header_Num   => Index,
      Element      => Natural,
      No_Element   => No_Element,
      Free_Element => Free,
      Key          => String_Access,
      Hash         => Hash,
      Equal        => "=");
   use SHT;

   type An_Index is range 0 .. 10_000;
   Elements : array (An_Index) of Natural;
   Element_Name   : array (An_Index) of String_Access;
   Elements_Found : array (An_Index) of Boolean;

   HT         : Instance;
   Elmt       : Natural;
   Elmt_Index : An_Index;
   Success    : Boolean;

   function Hash is new String_Utils.Hash (Index);

   procedure Free (X : in out Natural) is
      pragma Unreferenced (X);
   begin
      null;
   end Free;

   function Hash (F : String_Access) return Index is
   begin
      return Hash (F.all);
   end Hash;

   function Element_Value (J : An_Index) return Natural is
   begin
      return 3 * Natural (J) / 2 + 1;
      --  The rest of the test assumes this function is bijective.
   end Element_Value;

   procedure Get_Element_Index
     (V : Natural; VI : out An_Index; Success : out Boolean) is
   begin
      for K in An_Index'Range loop
         if Elements (K) = V then
            VI := K;
            Success := True;
            return;
         end if;
      end loop;
      Vi := An_Index'First;
      Success := False;
   end Get_Element_Index;

   function Element_Name_Of (J : An_Index) return String is
   begin
      if J <= 255 then
         return String'(1 => Character'Val (J mod 255));
      else
         return Character'Val (J mod 255) & Element_Name_Of (J / 255);
      end if;
   end Element_Name_Of;

   function Element_Name_Access (J : An_Index) return String_Access is
      Name : constant String := Element_Name_Of (J);
   begin
      return new String'(Name);
   end Element_Name_Access;

   procedure Check_Remove (J : An_Index) is
      E : Natural;
   begin
      Remove (HT, Element_Name (J));
      E := Get (HT, Element_Name (J));
      if E /= No_Element then
         Put_Line
           ("*** Value returned by Get is" & E'Img &
            " but it should be" & No_Element'Img);
      end if;
      Elements_Found (J) := True;
      --  Mark this element as found. This will be used later when we
      --  check that all elements are found, and found once when iterating
      --  over the hash-table...
   end Check_Remove;

   procedure Check_All_Elements_Found_Once_And_Only_Once_By_Iterator is
      Iter : Cursor;
   begin
      Get_First (HT, Iter);
      loop
         Elmt := Get_Element (Iter);
         exit when Elmt = No_Element;

         Get_Element_Index (Elmt, Elmt_Index, Success);
         if Success then
            if (Elements_Found (Elmt_Index)) then
               Put_Line
                 ("*** Element at index" & Elmt_Index'Img &
                  " found more than once.");
            end if;
            Elements_Found (Elmt_Index) := True;
         else
            Put_Line
              ("*** Strange value returned while iterating :" & Elmt'Img);
         end if;

         Get_Next (HT, Iter);
      end loop;

      --  Verify that all elements were found by the iterator...
      for J in Elements_Found'Range loop
         if not Elements_Found (J) then
            Put_Line
              ("*** Element at index" & J'Img & " not returned by iterator");
         end if;
      end loop;
   end Check_All_Elements_Found_Once_And_Only_Once_By_Iterator;

begin

   --  Initialize the Elements_Found array
   for J in An_Index'Range loop
      Elements (J)       := Element_Value (J);
      Element_Name (J)   := Element_Name_Access (J);
      Elements_Found (J) := False;
   end loop;

   if Verbose then
      Put_Line ("--- Filling-in the hash-table...");
   end if;

   --  Fill-in the htable:
   Reset (HT);
   for J in reverse An_Index loop
      --  Put_Line ("Index:" & J'Img);
      Set (HT, Element_Name (J), Element_Value (J));
   end loop;

   if Verbose then
      Put_Line ("--- Testing the values stored in the hash-table...");
   end if;

   --  check the values retrieved from the hash-table...
   for J in An_Index loop
      if Get (HT, Element_Name (J)) /= Element_Value (J) then
         Put_Line ("*** Simple.HTable.Get failed!");
         Put_Line
           ("       Expected: ('" & Element_Name (J).all & "'," &
            Natural'Image (Element_Value (J)) & ")");
         Put_LIne
           ("          Found: ('" & Element_Name (J).all & "'," &
            Natural'Image (Element_Value (J)) & ")");
      end if;
   end loop;

   if Verbose then
      Put_Line ("--- Verifying the hash-table iterator...");
   end if;

   Check_All_Elements_Found_Once_And_Only_Once_By_Iterator;

  if Verbose then
      Put_Line ("--- Verify that Remove functions properly...");
   end if;

   --  Reinitialize the Elements_Found array first
   for J in Elements_Found'Range loop
      Elements_Found (J) := False;
   end loop;

   Check_Remove (4);
   Check_Remove (8);
   Check_Remove (7);
   Check_All_Elements_Found_Once_And_Only_Once_By_Iterator;

   if Verbose then
      Put_Line ("--- Check that Reset works properly...");
   end if;

   Reset (HT);

   declare
      Iter : Cursor;
   begin
      Get_First (HT, Iter);
      if Get_Element (Iter) /= No_Element then
         Put_Line ("*** Reset did not empty the hash-table.");
      end if;
   end;

end Test_HTables;