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: CARDINALMIN[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];
};
}.