DIRECTORY Basics USING[BITAND, BITOR, BITSHIFT, BITXOR], TypeStrings USING[TypeString], TypeHash USING [TypeKey, nullKey, WordPerKey]; TypeHashImpl: MONITOR IMPORTS Basics EXPORTS TypeHash = BEGIN OPEN TypeStrings, TypeHash; KeyPtr: TYPE = LONG POINTER TO TypeKey; KeyAsChars: TYPE = PACKED ARRAY [0 .. CharsPerKey) OF CHAR; CharsPerKey: CARDINAL = 8; KeyAsCharsPtr: TYPE = LONG POINTER TO KeyAsChars; TypeStrHash: PUBLIC PROCEDURE[ts: TypeString] RETURNS[key: TypeKey _ nullKey] = { chars: CARDINAL _ ts.length; keyPtr: KeyPtr _ LOOPHOLE[ts, KeyPtr] + SIZE[StringBody]; AccumKey: PROC [temp: TypeKey] = INLINE { key[0] _ Basics.BITXOR[key[0], temp[0] ]; key[1] _ Basics.BITXOR[key[1], temp[1] ]; key[2] _ Basics.BITXOR[key[2], temp[2] ]; key[3] _ Basics.BITXOR[key[3], temp[3] ]; key[3] _ Basics.BITOR[Basics.BITSHIFT[key[3], 1], Basics.BITSHIFT[key[2], -15] ]; key[2] _ Basics.BITOR[Basics.BITSHIFT[key[2], 1], Basics.BITSHIFT[key[1], -15] ]; key[1] _ Basics.BITOR[Basics.BITSHIFT[key[1], 1], Basics.BITSHIFT[key[0], -15] ]; key[0] _ Basics.BITSHIFT[key[0], 1]; key[0] _ IF Basics.BITAND[key[0], 1] = 1 THEN key[0]-1 ELSE key[0]+1; }; WHILE chars >= CharsPerKey DO temp: TypeKey _ keyPtr^; AccumKey[temp]; keyPtr _ keyPtr + WordPerKey; chars _ chars - CharsPerKey; ENDLOOP; IF chars # 0 THEN { charKey: KeyAsChars _ ALL[0C]; charKeyPtr: KeyAsCharsPtr _ LOOPHOLE[keyPtr]; FOR i: NAT IN [0..chars) DO charKey[i] _ charKeyPtr[i]; ENDLOOP; AccumKey[LOOPHOLE[charKey]]; }; IF key[0] = 0 AND key[1] = 0 AND key[2] = 0 AND key[3] = 0 THEN { key[0] _ 1; }; }; END. ÌTypeHashImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Russ Atkinson, October 23, 1984 3:31:01 pm PDT TypeStrings is of type LONG STRING. Don't ever return a null type key! Ê™˜šœ™Jšœ Ïmœ1™