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