-- JaMHashImpl.mesa
-- Last changed by Doug Wyatt, 1-Oct-81 13:43:53
DIRECTORY
JaMBasic USING [Object],
JaMDict USING [],
JaMVM USING [GetText],
Inline USING [BITSHIFT, BITXOR, HighHalf, LowHalf];
JaMHashImpl: PROGRAM
IMPORTS JaMVM, Inline
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[Inline.LowHalf[k.ivalue]];
real => RETURN[Inline.HighHalf[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 ← Inline.BITXOR[Inline.BITSHIFT[h,1], text[i]];
ENDLOOP;
IF len >= 2 THEN FOR i: CARDINAL IN[len - 2..len) DO
h ← Inline.BITXOR[Inline.BITSHIFT[h,1], text[i]];
ENDLOOP;
RETURN[h] };
}.