DIRECTORY Ascii USING [Upper], Basics USING [BITOR, BITSHIFT, BITXOR], FSLock USING [ActiveFile, ActiveFileObject], FSBackdoor USING [Version], Rope USING [Concat, Equal, InlineFetch, Length, ROPE]; FSLockTableImpl: CEDAR MONITOR IMPORTS Ascii, Basics, Rope EXPORTS FSLock = { LookupLock: PUBLIC ENTRY PROC [prefix, nameBody: Rope.ROPE, version: FSBackdoor.Version] RETURNS [a: FSLock.ActiveFile] = { ENABLE UNWIND => NULL; hash: CARDINAL; IF Rope.InlineFetch[nameBody, 0] # '[ AND prefix # NIL THEN nameBody _ Rope.Concat[prefix, nameBody]; hash _ Hash[nameBody, version]; lookups _ lookups + 1; FOR a _ lockTbl[hash], a.next UNTIL a = NIL DO IF version = a.version AND Rope.Equal[nameBody, a.nameBody, FALSE] THEN RETURN; ENDLOOP; newActiveFiles _ newActiveFiles + 1; a _ NEW [FSLock.ActiveFileObject]; a.nameBody _ nameBody; a.version _ version; a.h _ NIL; a.fileLock _ none; a.recordLock _ FALSE; a.fileLockCount _ 0; a.attachedTo _ NIL; a.next _ lockTbl[hash]; lockTbl[hash] _ a; }; RemoveLock: PUBLIC ENTRY PROC [a: FSLock.ActiveFile] = { ENABLE UNWIND => NULL; hash: CARDINAL = Hash[a.nameBody, a.version]; aPrev: FSLock.ActiveFile _ lockTbl[hash]; removals _ removals + 1; IF aPrev = a THEN lockTbl[hash] _ a.next ELSE DO IF aPrev.next = a THEN {aPrev.next _ a.next; EXIT}; aPrev _ aPrev.next; ENDLOOP; a.nameBody _ NIL; }; lookups: INT _ 0; newActiveFiles: INT _ 0; removals: INT _ 0; buckets: CARDINAL = 509; LockTable: TYPE = ARRAY [0..buckets) OF FSLock.ActiveFile; lockTbl: REF LockTable _ NEW [LockTable _ ALL[NIL]]; Hash: PROC [name: Rope.ROPE, v: FSBackdoor.Version] RETURNS [hash: CARDINAL] = { OPEN Basics; len: CARDINAL = Rope.Length[name]; hash _ len + v; FOR i: CARDINAL _ 0, i+ 2 WHILE i < len DO hash _ BITOR[BITSHIFT[hash, 1], BITSHIFT[hash, -15]]; hash _ BITXOR[BITSHIFT[CHAR[Ascii.Upper[Rope.InlineFetch[name, i]]].ORD, 8], hash]; IF i+1 < len THEN hash _ BITXOR[CHAR[Ascii.Upper[Rope.InlineFetch[name, i+1]]].ORD, hash]; ENDLOOP; hash _ hash MOD buckets; }; Stats: ENTRY PROC RETURNS [items, longestChain: INT, chains: ARRAY [0..10] OF CARDINAL] = { ENABLE UNWIND => NULL; items _ 0; longestChain _ 0; chains _ ALL[0]; FOR i: CARDINAL IN [0 .. buckets) DO chainLength: INT _ 0; cIndex: CARDINAL; FOR a: FSLock.ActiveFile _ lockTbl[i], a.next UNTIL a = 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; }; }. FSLockTableImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Russ Atkinson, November 7, 1984 11:30:18 am PST Schroeder, November 15, 1983 1:29 pm Levin, August 9, 1983 11:39 am Exported to FSLock Statistics Lock Table AFT statistics Κ'– "cedar" style˜šœ™Jšœ Οmœ1™L˜Lšžœ˜—Lšœ˜Lšžœžœ˜>Lšœ žœ˜Lšœ$˜$Lšžœ˜—Lšœ˜——Lšœ˜—…— Θσ