From: Michael R on
Hi Folks,

I'd like to use the generic Hashed_Maps container to store mappings
from a set of small integers (three) to Wide_Strings
(Indefinite_Hashed_Maps):

(1, 10, 4) => "ABC",
(10, 3, 5) => "XYZ",

Does anyone have recommendations on how best to implement the Hash
function for keys like this?

Take care,
Michael.
From: John B. Matthews on
In article
<50701baa-7c05-450c-a42d-c699516ddc00(a)t14g2000prm.googlegroups.com>,
Michael R <michael(a)zanyblue.com> wrote:

> Hi Folks,
>
> I'd like to use the generic Hashed_Maps container to store mappings
> from a set of small integers (three) to Wide_Strings
> (Indefinite_Hashed_Maps):
>
> (1, 10, 4) => "ABC",
> (10, 3, 5) => "XYZ",
>
> Does anyone have recommendations on how best to implement the Hash
> function for keys like this?

I'd try something simple like shift and add, but it might depend on the
definition of "small".

Whatever you decide, here's some code I used to examine the distribution
of collisions in a map keyed by "/usr/share/dict/words":

$ ./collisions
0: 218586 (55.59%)
1: 126250 (32.10%)
2: 38432 (9.77%)
3: 8362 (2.13%)
4: 1354 (0.34%)
5: 229 (0.06%)
6: 24 (0.01%)
7: 4 (0.00%)
8: 1 (0.00%)

<http://home.roadrunner.com/~jbmatthews/jumble.html#sec2>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
From: Simon Wright on
Michael R <michael(a)zanyblue.com> writes:

> Hi Folks,
>
> I'd like to use the generic Hashed_Maps container to store mappings
> from a set of small integers (three) to Wide_Strings
> (Indefinite_Hashed_Maps):
>
> (1, 10, 4) => "ABC",
> (10, 3, 5) => "XYZ",
>
> Does anyone have recommendations on how best to implement the Hash
> function for keys like this?

I don't know about 'best', but in ColdFrame
(http://coldframe.sourceforge.net/coldframe/) I would generate this hash
for use with Booch Maps, where the key components of Instance are
{A:Integer, B:Integer, C:Integer}:

function Instance_Hash (I : Instance) return Natural is
type M is mod 2**31;
Result : M := 0;
begin
Result := Result xor M (I.A mod 2**31);
Result := Result * 10019;
Result := Result xor M (I.B mod 2**31);
Result := Result * 10019;
Result := Result xor M (I.C mod 2**31);
Result := Result * 10019;
return Natural (Result);
end Instance_Hash;

I believe the 10019 came from Knuth, but can't see a reference.
From: Michael R on
On Apr 23, 2:39 pm, Simon Wright <si...(a)pushface.org> wrote:
> Michael R <mich...(a)zanyblue.com> writes:
> > Hi Folks,
>
> > I'd like to use the generic Hashed_Maps container to store mappings
> > from a set of small integers (three) to Wide_Strings
> > (Indefinite_Hashed_Maps):
>
> > (1, 10, 4) => "ABC",
> > (10, 3, 5) => "XYZ",
>
> > Does anyone have recommendations on how best to implement the Hash
> > function for keys like this?
>
> I don't know about 'best', but in ColdFrame
> (http://coldframe.sourceforge.net/coldframe/) I would generate this hash
> for use with Booch Maps, where the key components of Instance are
> {A:Integer, B:Integer, C:Integer}:
>
>    function Instance_Hash (I : Instance) return Natural is
>       type M is mod 2**31;
>       Result : M := 0;
>    begin
>       Result := Result xor M (I.A mod 2**31);
>       Result := Result * 10019;
>       Result := Result xor M (I.B mod 2**31);
>       Result := Result * 10019;
>       Result := Result xor M (I.C mod 2**31);
>       Result := Result * 10019;
>       return Natural (Result);
>    end Instance_Hash;
>
> I believe the 10019 came from Knuth, but can't see a reference.

Hi,

Thank you for this suggestion. Just fyi, my GNAT 4.4.3 compiler
generated

xtest.adb:20:40: value not in range of type "Standard.Integer"
xtest.adb:20:40: static expression fails Constraint_Check

for "M (I.A mod 2**31)" expressions. Rephrasing as

Result := Result xor M'Mod (I.A);

compiled OK.

Take care,
Michael.
From: Jeffrey R. Carter on
Michael R <michael(a)zanyblue.com> writes:

> I'd like to use the generic Hashed_Maps container to store mappings
> from a set of small integers (three) to Wide_Strings
> (Indefinite_Hashed_Maps):
>
> (1, 10, 4) => "ABC",
> (10, 3, 5) => "XYZ",
>
> Does anyone have recommendations on how best to implement the Hash
> function for keys like this?

What is the definition of "small"? If it has a defined range, for example:

subtype Small is Natural range Low .. High;

then you can define

Offset = 0 - Low
Max = High + Offset

and for X = # bits needed to represent Max, if 3 * X <=
Ada.Containers.Hash_Type'Size, then you can do a perfect hash:

type Triple is record
A : Small;
B : Small;
C : Small;
end record;

Hash (R : Triple) = Shift_Left (R.A + Offset, 2 * X) or
Shift_Left (R.B + Offset, X) or
(R.C + Offset)

--
Jeff Carter
"I was in love with a beautiful blonde once, dear.
She drove me to drink. That's the one thing I'm
indebted to her for."
Never Give a Sucker an Even Break
109