JaMHashImpl.mesa
Doug Wyatt, 1-Oct-81 13:43:53
Russ Atkinson, July 22, 1983 6:18 pm
DIRECTORY
Basics USING [BITSHIFT, BITXOR, HighHalf, LowHalf],
JaMBasic USING [Object],
JaMDict USING [],
JaMVM USING [GetText];
JaMHashImpl:
PROGRAM
IMPORTS JaMVM, Basics
EXPORTS JaMDict = {
OPEN VM:JaMVM, JaMBasic;
HashObject:
PUBLIC
PROC[key: Object]
RETURNS[
CARDINAL] = {
hashes object key into a CARDINAL
Expects caller to do: (h MOD range) to allow for different ranges with same key
WITH k: key
SELECT
FROM
integer => RETURN[Basics.LowHalf[k.ivalue]];
real => RETURN[Basics.HighHalf[LOOPHOLE[k.rvalue]]];
boolean => RETURN[LOOPHOLE[k.bvalue]];
name => RETURN[k.id.index];
string => RETURN[HashString[k]];
stream => RETURN[k.index];
command => RETURN[k.index];
ENDCASE => RETURN[0];
};
HashString and HashText must be consistent!
maxLength: CARDINAL = 20;
HashString:
PUBLIC
PROC[s: string Object]
RETURNS[
CARDINAL] = {
text: STRING ← [maxLength]; VM.GetText[s,text];
RETURN[InlineHash[text,s.length]] };
HashText:
PUBLIC
PROC[text:
LONG
STRING]
RETURNS[
CARDINAL] = {
RETURN[InlineHash[text,text.length]] };
InlineHash:
PROC[text:
LONG
STRING, h:
CARDINAL]
RETURNS[
CARDINAL] =
INLINE {
len: CARDINAL ← MIN[text.length,maxLength];
FOR i:
CARDINAL
IN[1..
MIN[3,len])
DO
h ← Basics.BITXOR[Basics.BITSHIFT[h,1], LOOPHOLE[text[i]]];
ENDLOOP;
IF len >= 2
THEN
FOR i:
CARDINAL
IN[len - 2..len)
DO
h ← Basics.BITXOR[Basics.BITSHIFT[h,1], LOOPHOLE[text[i]]];
ENDLOOP;
RETURN[h];
};
}.