TypeHashImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) August 30, 1985 6:01:07 pm PDT
DIRECTORY
Basics USING [bytesPerWord],
Checksum USING [ComputeChecksum],
TypeStrings USING [TypeString],
TypeHash USING [TypeKey, nullKey];
TypeHashImpl:
MONITOR
IMPORTS Checksum
EXPORTS TypeHash =
BEGIN OPEN TypeStrings;
TypeKey:
TYPE = TypeHash.TypeKey;
nullKey: TypeKey = TypeHash.nullKey;
KeyPtr: TYPE = LONG POINTER TO TypeKey;
KeyAsChars:
TYPE =
PACKED ARRAY [0 .. CharsPerKey)
OF
CHAR;
WordsPerKey: CARDINAL = SIZE[TypeKey];
CharsPerKey: CARDINAL = Basics.bytesPerWord*WordsPerKey;
KeyAsCharsPtr: TYPE = LONG POINTER TO KeyAsChars;
DoubleKey: TYPE = RECORD [key1: TypeKey, key2: TypeKey];
EndBytes: TYPE = PACKED ARRAY [0..Basics.bytesPerWord) OF CHAR;
EndBytesPtr: TYPE = LONG POINTER TO EndBytes;
TypeStrHash:
PUBLIC
PROC [ts: TypeString]
RETURNS [key: TypeKey ← nullKey] = {
TypeStrings is of type LONG STRING.
chars: CARDINAL ← ts.length;
ptr: LONG POINTER TO CARDINAL ← LOOPHOLE[ts+SIZE[StringBody]];
double: DoubleKey ← [nullKey, nullKey];
pos: CARDINAL ← 0;
double.key1[0] ← chars+1;
WHILE chars >= Basics.bytesPerWord
DO
mod: [0..WordsPerKey) ← pos MOD WordsPerKey;
double.key2[mod] ← (ptr+pos)^;
pos ← pos + SIZE[CARDINAL];
double.key1[mod] ← Checksum.ComputeChecksum[pos, WordsPerKey+1, @double.key1[mod]];
chars ← chars - Basics.bytesPerWord;
ENDLOOP;
IF chars # 0
THEN {
endBytesPtr: EndBytesPtr ← LOOPHOLE[ptr+pos];
endBytes: EndBytes ← ALL[0C];
mod: [0..WordsPerKey) ← pos MOD WordsPerKey;
FOR i:
NAT
IN [0..chars)
DO
endBytes[i] ← endBytesPtr[i];
ENDLOOP;
double.key2[mod] ← LOOPHOLE[endBytes];
double.key1[mod] ←
Checksum.ComputeChecksum[pos+1, WordsPerKey+1, @double+(pos MOD WordsPerKey)];
};
key ← double.key1;
IF key[0] = 0
AND key[1] = 0
AND key[2] = 0
AND key[3] = 0
THEN {
Don't ever return a null type key!
key[0] ← chars+1;
};
};
END.