DIRECTORY Rope USING [Equal, ROPE], RTTCache, SafeStorage USING [Type]; RTTCacheImpl: CEDAR MONITOR IMPORTS Rope EXPORTS RTTCache = BEGIN OPEN Rope, RTTCache, SafeStorage; InvalidIndex: PUBLIC ERROR = CODE; HashSize: CARDINAL = 256; HashRange: TYPE = CARDINAL [0..HashSize); intCache: IntCache _ NEW[IntCacheRep]; IntCache: TYPE = REF IntCacheRep; IntCacheRep: TYPE = RECORD [ enabled: BOOL _ TRUE, probes, misses, filled: INT _ 0, hashVec: ARRAY HashRange OF IntEntry]; refCache: RefCache _ NEW[RefCacheRep]; RefCache: TYPE = REF RefCacheRep; RefCacheRep: TYPE = RECORD [ enabled: BOOL _ TRUE, probes, misses, filled: INT _ 0, hashVec: ARRAY HashRange OF RefEntry]; Hash: PROC [type: Type, proc: ProcKey] RETURNS [HashRange] = { RETURN [(LOOPHOLE[type, CARDINAL] + LOOPHOLE[proc, CARDINAL]) MOD HashSize]; }; LookupInt: PUBLIC ENTRY PROC [type: Type, proc: ProcKey] RETURNS [entry: IntEntry] = { ENABLE UNWIND => NULL; hash: HashRange _ Hash[type, proc]; intCache.probes _ intCache.probes + 1; FOR entry _ intCache.hashVec[hash], entry.next WHILE entry # NIL DO IF entry.type = type AND entry.proc = proc THEN RETURN; ENDLOOP; entry _ NEW[IntEntryRep _ [next: intCache.hashVec[hash], type: type, proc: proc]]; intCache.hashVec[hash] _ entry; intCache.misses _ intCache.misses + 1; }; FillIntEntry: PUBLIC ENTRY PROC [entry: IntEntry, value: INT] RETURNS [alreadyFull: BOOL] = { ENABLE UNWIND => NULL; IF NOT intCache.enabled THEN RETURN [TRUE]; IF entry.valid THEN RETURN [TRUE]; entry.int _ value; entry.valid _ TRUE; intCache.filled _ intCache.filled + 1; RETURN [FALSE]; }; ClearIntEntry: PUBLIC ENTRY PROC [entry: IntEntry] = { ENABLE UNWIND => NULL; IF NOT entry.valid THEN RETURN; entry.int _ -1; entry.valid _ FALSE; intCache.filled _ intCache.filled - 1; }; GetInt: PUBLIC ENTRY PROC [entry: IntEntry] RETURNS [value: INT, valid: BOOL] = { RETURN [entry.int, entry.valid]; }; LookupRef: PUBLIC ENTRY PROC [type: Type, proc: ProcKey] RETURNS [entry: RefEntry] = { ENABLE UNWIND => NULL; hash: HashRange _ Hash[type, proc]; refCache.probes _ refCache.probes + 1; FOR entry _ refCache.hashVec[hash], entry.next WHILE entry # NIL DO IF entry.type = type AND entry.proc = proc THEN RETURN; ENDLOOP; entry _ NEW[RefEntryRep _ [next: refCache.hashVec[hash], type: type, proc: proc]]; refCache.hashVec[hash] _ entry; refCache.misses _ refCache.misses + 1; }; FillRefEntry: PUBLIC ENTRY PROC [entry: RefEntry, value: REF] RETURNS [alreadyFull: BOOL] = { ENABLE UNWIND => NULL; IF NOT refCache.enabled THEN RETURN [TRUE]; IF entry.valid THEN RETURN [TRUE]; entry.ref _ value; entry.valid _ TRUE; refCache.filled _ refCache.filled + 1; RETURN [FALSE]; }; ClearRefEntry: PUBLIC ENTRY PROC [entry: RefEntry] = { ENABLE UNWIND => NULL; IF NOT entry.valid THEN RETURN; entry.ref _ NIL; entry.valid _ FALSE; refCache.filled _ refCache.filled - 1; }; GetRef: PUBLIC ENTRY PROC [entry: RefEntry] RETURNS [value: REF, valid: BOOL] = { RETURN [entry.ref, entry.valid]; }; GetStats: PUBLIC ENTRY PROC RETURNS [intProbes, intMisses, intFilled, refProbes, refMisses, refFilled: INT] = { ENABLE UNWIND => NULL; RETURN [intCache.probes, intCache.misses, intCache.filled, refCache.probes, refCache.misses, refCache.filled]; }; NewComponentMap: PUBLIC PROC [len: NAT] RETURNS [map: ComponentMap] = { map _ NEW[ComponentMapRep[len]]; FOR i: NAT IN [0..len) DO map[i] _ NullComponentEntry; ENDLOOP; }; FillNameComponent: PUBLIC ENTRY PROC [map: ComponentMap, index: INT, name: ROPE] RETURNS [alreadyFull: BOOL] = { ENABLE UNWIND => NULL; x: NAT _ 0; IF index < 0 OR index >= map.len THEN RETURN WITH ERROR InvalidIndex; x _ index; IF map[x].validName THEN RETURN [TRUE]; map[x].name _ name; map[x].validName _ TRUE; map.filledNames _ map.filledNames + 1; RETURN [FALSE]; }; FillTypeComponent: PUBLIC ENTRY PROC [map: ComponentMap, index: INT, type: Type] RETURNS [alreadyFull: BOOL] = { ENABLE UNWIND => NULL; x: NAT _ 0; IF index < 0 OR index >= map.len THEN RETURN WITH ERROR InvalidIndex; x _ index; IF map[x].validType THEN RETURN [TRUE]; map[x].type _ type; map[x].validType _ TRUE; map.filledTypes _ map.filledTypes + 1; RETURN [FALSE]; }; GetComponentAtIndex: PUBLIC ENTRY PROC [map: ComponentMap, index: INT] RETURNS [comp: ComponentEntry] = { ENABLE UNWIND => NULL; IF index NOT IN [0..map.len) THEN RETURN WITH ERROR InvalidIndex; RETURN [map[index]]; }; GetComponentForName: PUBLIC ENTRY PROC [map: ComponentMap, name: ROPE, case: BOOL _ TRUE] RETURNS [index: INT, comp: ComponentEntry] = { ENABLE UNWIND => NULL; FOR i: NAT IN [0..map.len) DO comp: ComponentEntry _ map[i]; IF Rope.Equal[name, comp.name, case] THEN RETURN [i, comp]; ENDLOOP; RETURN [-1, NullComponentEntry]; }; DisableAndFlushIntCache: ENTRY PROC = { ENABLE UNWIND => NULL; intCache.enabled _ FALSE; intCache.probes _ intCache.misses _ intCache.filled _ 0; FOR i: HashRange IN HashRange DO FOR list: IntEntry _ intCache.hashVec[i], list.next UNTIL list = NIL DO list.valid _ FALSE; list.int _ -1; ENDLOOP; ENDLOOP; }; DisableAndFlushRefCache: ENTRY PROC = { ENABLE UNWIND => NULL; refCache.enabled _ FALSE; refCache.probes _ refCache.misses _ refCache.filled _ 0; FOR i: HashRange IN HashRange DO FOR list: RefEntry _ refCache.hashVec[i], list.next UNTIL list = NIL DO list.valid _ FALSE; list.ref _ NIL; ENDLOOP; ENDLOOP; }; DisableAndFlushAllCaches: PROC = { DisableAndFlushIntCache[]; DisableAndFlushRefCache[]; }; END. BRTTCacheImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Russ Atkinson, February 11, 1985 12:39:11 pm PST Rovner On June 30, 1983 12:15 pm atomically retrieves the value in the entry atomically retrieves the value in the entry atomically returns the given component entry will ERROR InvalidIndex if index NOT IN [0..map.len) atomically returns the given component entry for the given name IF case = TRUE, then name search is case-sensitive (Rope convention) will return [-1, NullComponentEntry] if no such name internal procs for flushing the cache ΚΓ˜codešœ™Kšœ Οmœ1™š žœžœžœžœžœ˜=Kšžœ ˜—K˜K˜—š Ÿ œžœžœžœžœ˜VKšžœžœžœ˜K˜#K˜&šžœ,žœ žœž˜CKšžœžœžœžœ˜7Kšžœ˜—KšœžœG˜RK˜K˜&K˜K˜—šŸ œžœžœžœžœžœžœ˜]Kšžœžœžœ˜Kš žœžœžœžœžœ˜+Kšžœ žœžœžœ˜"K˜Kšœžœ˜K˜&Kšžœžœ˜K˜K˜—šŸ œžœžœžœ˜6Kšžœžœžœ˜Kšžœžœ žœžœ˜K˜Kšœžœ˜K˜&K˜K˜—šŸœžœžœžœžœ žœ žœ˜QKšœ+™+Kšžœ˜ K˜K˜—š Ÿ œžœžœžœžœ˜VKšžœžœžœ˜K˜#K˜&šžœ,žœ žœž˜CKšžœžœžœžœ˜7Kšžœ˜—KšœžœG˜RK˜K˜&K˜K˜—šŸ œžœžœžœžœžœžœ˜]Kšžœžœžœ˜Kš žœžœžœžœžœ˜+Kšžœ žœžœžœ˜"K˜Kšœžœ˜K˜&Kšžœžœ˜K˜K˜—šŸ œžœžœžœ˜6Kšžœžœžœ˜Kšžœžœ žœžœ˜Kšœ žœ˜Kšœžœ˜K˜&K˜K˜—šŸœžœžœžœžœ žœ žœ˜QKšœ+™+Kšžœ˜ K˜K˜—š Ÿœžœžœž œDžœ˜oKšžœžœžœ˜šžœ4˜:K˜3—K˜K˜—š Ÿœžœžœžœžœ˜GKšœžœ˜ šžœžœžœ ž˜K˜Kšžœ˜—K˜K˜—šŸœžœžœžœžœžœžœžœ˜pKšžœžœžœ˜Kšœžœ˜ Kš žœ žœžœžœžœžœ˜EK˜ Kšžœžœžœžœ˜'K˜Kšœžœ˜K˜&Kšžœžœ˜K˜K˜—šŸœžœžœžœžœžœžœ˜pKšžœžœžœ˜Kšœžœ˜ Kš žœ žœžœžœžœžœ˜EK˜ Kšžœžœžœžœ˜'K˜Kšœžœ˜K˜&Kšžœžœ˜K˜K˜—š Ÿœžœžœžœžœžœ˜iKšœ,™,Kšœ4™4Kšžœžœžœ˜Kšžœžœžœžœžœžœžœ˜AKšžœ˜K˜K˜—šŸœžœžœžœžœžœžœžœ žœ˜ˆKšœ?™?KšœD™DKšœ4™4Kšžœžœžœ˜šžœžœžœž˜K˜šžœ#ž˜)Kšžœ ˜—Kšžœ˜—Kšžœ˜ K˜K˜—Kšœ%™%K˜šŸœžœžœ˜'Kšžœžœžœ˜Kšœžœ˜K˜8šžœžœ ž˜ šžœ1žœžœž˜GKšœ žœ˜K˜Kšžœ˜—Kšžœ˜—K˜K˜—šŸœžœžœ˜'Kšžœžœžœ˜Kšœžœ˜K˜8šžœžœ ž˜ šžœ1žœžœž˜GKšœ žœ˜Kšœ žœ˜Kšžœ˜—Kšžœ˜—K˜K˜—šŸœžœ˜"K˜K˜K˜K˜——Kšžœ˜K˜K˜—…—& +