<> <> <> <<>> DIRECTORY Checksum USING [ComputeChecksum], ImagerFontPrivate USING [FontAtom, FontAtomRep], ImagerTransformation USING [Copy, Equal, Transformation, TransformationRep], ImagerTypeface USING [Typeface], PrincOps USING [zXOR]; ImagerFontAtomImpl: CEDAR MONITOR IMPORTS Checksum, ImagerTransformation EXPORTS ImagerFontPrivate ~ BEGIN FontAtom: TYPE ~ ImagerFontPrivate.FontAtom; FontAtomRep: TYPE ~ ImagerFontPrivate.FontAtomRep; Typeface: TYPE ~ ImagerTypeface.Typeface; Transformation: TYPE ~ ImagerTransformation.Transformation; TransformationRep: TYPE ~ ImagerTransformation.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 ImagerTransformation.Equal[f.m, m] THEN RETURN[f] ELSE misses _ misses+1; ENDLOOP; { f: FontAtom ~ NEW[FontAtomRep _ [typeface: typeface, m: ImagerTransformation.Copy[m]]]; hashTable[hashIndex] _ CONS[f, head]; entries _ entries+1; IF head#NIL THEN collisions _ collisions+1; RETURN[f]; }; }; END.