[Ada] Pair miscount in Dynamic_HTable.Put

This patch corrects the logic of GNAT.Dynamic_HTables.Dynamic_HTable.Put to
update the number of key-value pairs in the hash table only when the put is
adding a new pair, rather than updating the value of an existing pair.

2018-09-26  Hristian Kirtchev  <kirtchev@adacore.com>

gcc/ada/

	* libgnat/g-dynhta.adb (Prepend_Or_Replace): Update the number
	of key-value pairs in the hash table only when adding a brand
	new pair.

gcc/testsuite/

	* gnat.dg/dynhash1.adb: New testcase.

From-SVN: r264623
This commit is contained in:
Hristian Kirtchev 2018-09-26 09:18:23 +00:00 committed by Pierre-Marie de Rodat
parent 3e4ade66c6
commit 4f95defaa9
4 changed files with 71 additions and 2 deletions

View file

@ -1,3 +1,9 @@
2018-09-26 Hristian Kirtchev <kirtchev@adacore.com>
* libgnat/g-dynhta.adb (Prepend_Or_Replace): Update the number
of key-value pairs in the hash table only when adding a brand
new pair.
2018-09-26 Sergey Rybin <rybin@adacore.com>
* doc/gnat_ugn/gnat_utility_programs.rst: Add note about

View file

@ -544,6 +544,9 @@ package body GNAT.Dynamic_HTables is
Detach (Nod);
Free (Nod);
-- The number of key-value pairs is updated when the hash table
-- contains a valid node which represents the pair.
T.Pairs := T.Pairs - 1;
-- Compress the hash table if the load factor drops below
@ -1121,6 +1124,11 @@ package body GNAT.Dynamic_HTables is
Nod := new Node'(Key, Value, null, null);
Prepend (Nod, Head);
-- The number of key-value pairs must be updated for a prepend,
-- never for a replace.
T.Pairs := T.Pairs + 1;
end Prepend_Or_Replace;
-- Local variables
@ -1148,8 +1156,6 @@ package body GNAT.Dynamic_HTables is
Prepend_Or_Replace (Head);
T.Pairs := T.Pairs + 1;
-- Expand the hash table if the ratio of pairs to buckets goes over
-- Expansion_Threshold.

View file

@ -1,3 +1,7 @@
2018-09-26 Hristian Kirtchev <kirtchev@adacore.com>
* gnat.dg/dynhash1.adb: New testcase.
2018-09-26 Hristian Kirtchev <kirtchev@adacore.com>
* gnat.dg/sets1.adb: New testcase.

View file

@ -0,0 +1,53 @@
with Ada.Text_IO; use Ada.Text_IO;
with GNAT; use GNAT;
with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
procedure Dynhash1 is
function Hash (Key : Integer) return Bucket_Range_Type is
begin
return Bucket_Range_Type (Key);
end Hash;
package Integer_Hash_Tables is new Dynamic_HTable
(Key_Type => Integer,
Value_Type => Integer,
No_Value => 0,
Expansion_Threshold => 1.3,
Expansion_Factor => 2,
Compression_Threshold => 0.3,
Compression_Factor => 2,
"=" => "=",
Hash => Hash);
use Integer_Hash_Tables;
Siz : Natural;
T : Instance;
begin
T := Create (8);
Put (T, 1, 1);
Put (T, 1, 2);
Put (T, 1, 3);
Siz := Size (T);
if Siz /= 1 then
Put_Line ("ERROR: Put: wrong size");
Put_Line ("expected: 1");
Put_Line ("got :" & Siz'Img);
end if;
Delete (T, 1);
Delete (T, 1);
Siz := Size (T);
if Siz /= 0 then
Put_Line ("ERROR: Delete: wrong size");
Put_Line ("expected: 0");
Put_Line ("got :" & Siz'Img);
end if;
Destroy (T);
end Dynhash1;