FSPkgRefImpl.mesa
Last Edited by: Schroeder, November 15, 1983 1:35 pm
DIRECTORY
FSLock;
FSPkgRefImpl: CEDAR MONITOR
EXPORTS FSLock
= BEGIN
Exported to FSOpenFile
RecordREF: PUBLIC ENTRY PROC [r: REF] =
BEGIN
p: REF PRTEntry = NEW [PRTEntry];
hash: CARDINAL = Hash[r];
p.ref ← r;
p.chain ← prt[hash];
prt[hash] ← p;
recorded ← recorded + 1;
END;
RemoveREF: PUBLIC ENTRY PROC [r: REF] =
BEGIN
hash: CARDINAL = Hash[r];
p, q: REF PRTEntry;
q ← prt[hash];
IF q.ref = r
THEN prt[hash] ← q.chain
ELSE DO
p ← q;
q ← q.chain;
IF q.ref = r THEN {p.chain ← q.chain; EXIT};
ENDLOOP;
q.ref ← NIL;
removed ← removed + 1;
END;
Package Reference Table
buckets: CARDINAL = 251;
PackageReferenceTable: TYPE = ARRAY [0..buckets) OF REF PRTEntry;
PRTEntry: TYPE = RECORD [chain: REF PRTEntry, ref: REF];
prt: REF PackageReferenceTable ← NEW [PackageReferenceTable ← ALL[NIL]];
Hash: PROC [r: REF] RETURNS [CARDINAL] = INLINE
{ RETURN [ LOOPHOLE[r, LONG CARDINAL] MOD buckets] };
PRT statistics
recorded, removed: INT ← 0;
Stats: ENTRY PROC RETURNS [items, longestChain: INT, chains: ARRAY [0..10] OF CARDINAL] =
BEGIN
items ← 0;
longestChain ← 0;
chains ← ALL[0];
FOR i: CARDINAL IN [0 .. buckets) DO
chainLength: INT ← 0;
cIndex: CARDINAL;
FOR p: REF PRTEntry ← prt[i], p.chain UNTIL p = NIL DO
chainLength ← chainLength + 1;
ENDLOOP;
items ← items + chainLength;
IF chainLength > longestChain THEN longestChain ← chainLength;
cIndex ← MIN [chainLength, 10];
chains[cIndex] ← chains[cIndex] + 1;
ENDLOOP;
END;
END.