<> <> <> <<>> DIRECTORY Checksum USING [ComputeChecksum], IIFontPrivate USING [FontAtom, FontAtomRep], IITransformation USING [Copy, Equal, Transformation, TransformationRep], IITypeface USING [Typeface], PrincOps USING [zXOR]; IIFontAtomImpl: CEDAR MONITOR IMPORTS Checksum, IITransformation EXPORTS IIFontPrivate ~ BEGIN FontAtom: TYPE ~ IIFontPrivate.FontAtom; FontAtomRep: TYPE ~ IIFontPrivate.FontAtomRep; Typeface: TYPE ~ IITypeface.Typeface; Transformation: TYPE ~ IITransformation.Transformation; TransformationRep: TYPE ~ IITransformation.TransformationRep; hashTableSize: NAT ~ 253; HashIndex: TYPE ~ [0..hashTableSize); HashTable: TYPE ~ REF HashTableRep; HashTableRep: TYPE ~ ARRAY HashIndex OF FontAtomList; FontAtomList: TYPE ~ LIST OF FontAtom; hashTable: HashTable ~ NEW[HashTableRep _ ALL[NIL]]; entries: INT _ 0; collisions: INT _ 0; misses: INT _ 0; Munch: PROC [LONG CARDINAL] RETURNS [CARDINAL] ~ TRUSTED MACHINE CODE { PrincOps.zXOR }; Hash: PROC [typeface: Typeface, m: Transformation] RETURNS [CARDINAL] ~ TRUSTED INLINE { RETURN[Checksum.ComputeChecksum[cs: Munch[LOOPHOLE[typeface]], nWords: SIZE[TransformationRep], p: LOOPHOLE[m]]]; }; MakeFontAtom: PUBLIC ENTRY PROC [typeface: Typeface, m: Transformation] RETURNS [FontAtom] ~ { ENABLE UNWIND => NULL; hash: CARDINAL ~ Hash[typeface, m]; hashIndex: HashIndex ~ hash MOD hashTableSize; head: FontAtomList ~ hashTable[hashIndex]; FOR each: FontAtomList _ head, each.rest UNTIL each=NIL DO f: FontAtom ~ each.first; IF f.typeface=typeface AND IITransformation.Equal[f.m, m] THEN RETURN[f] ELSE misses _ misses+1; ENDLOOP; { f: FontAtom ~ NEW[FontAtomRep _ [typeface: typeface, m: IITransformation.Copy[m]]]; hashTable[hashIndex] _ CONS[f, head]; entries _ entries+1; IF head#NIL THEN collisions _ collisions+1; RETURN[f]; }; }; END.