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 CARDINALLOOPHOLE[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.