DIRECTORY Basics, DocCache, FS, HashTable, PutGet, RedBlackTree, Rope, TiogaOps, ViewerClasses, ViewerOps; DocCacheImpl: CEDAR MONITOR IMPORTS FS, HashTable, PutGet, RedBlackTree, Rope, TiogaOps, ViewerOps EXPORTS DocCache = BEGIN OPEN DocCache; byRef: RedBlackTree.Table = RedBlackTree.Create[GetRef, CompareRef]; byName: HashTable.Table = HashTable.Create[equal: HashTable.RopeEqualModCase, hash: HashTable.HashRopeModCase]; lastRef: INT _ FIRST[INT]; lastFile: ROPE _ NIL; lastDoc: TiogaNode _ NIL; cacheLimit: NAT _ 10; GetRef: PROC [data: REF ANY] RETURNS [key: REF INT] --RedBlackTree.GetKey-- = { e: Entry = NARROW[data]; key _ e.ref; }; CompareRef: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- = { k1: REF INT = NARROW[k]; k2: REF INT = GetRef[data]; c _ SELECT k1^ FROM < k2^ => less, = k2^ => equal, > k2^ => greater, ENDCASE => ERROR; }; Entry: TYPE = REF EntryPrivate; EntryPrivate: TYPE = RECORD [ fullFileName: ROPE, doc: TiogaNode, ref: REF INT ]; GetDoc: PUBLIC PROC [fileName: ROPE] RETURNS [doc: TiogaNode] = { ENABLE FS.Error => {doc _ NIL; CONTINUE}; fullFileName: ROPE = IF FS.ExpandName[fileName].cp.ver.length = 0 THEN FS.FileInfo[fileName].fullFName ELSE fileName; Search: PROC [v: ViewerClasses.Viewer] RETURNS [continue: BOOL _ TRUE]--ViewerOps.EnumProc-- = { IF v.file.Equal[fullFileName, FALSE] AND v.class.flavor = $Text THEN { tor: TiogaOps.Ref = TiogaOps.ViewerDoc[v]; IF tor # NIL THEN { TRUSTED {doc _ LOOPHOLE[tor]}; continue _ FALSE; }; }; }; GetFromCache: ENTRY PROC = { ENABLE UNWIND => { byRef.DestroyTable[]; byName.Erase[]; lastRef _ FIRST[INT]}; e: Entry; IF fullFileName.Equal[lastFile, FALSE] THEN {doc _ lastDoc; RETURN}; e _ NARROW[byName.Fetch[fullFileName].value]; IF e = NIL THEN { doc _ PutGet.FromFile[fullFileName]; e _ NEW [EntryPrivate _ [ fullFileName, doc, NEW [INT _ lastRef _ lastRef + 1] ]]; WHILE byRef.Size[] >= cacheLimit DO lru: Entry = NARROW[byRef.LookupSmallest[]]; [] _ byRef.Delete[lru.ref]; [] _ byName.Delete[lru.fullFileName]; ENDLOOP; IF NOT byName.Insert[fullFileName, e] THEN ERROR; byRef.Insert[e, e.ref]; } ELSE { doc _ e.doc; [] _ byRef.Delete[e.ref]; e.ref^ _ lastRef _ lastRef + 1; byRef.Insert[e, e.ref]; }; lastFile _ fullFileName; lastDoc _ doc; }; doc _ NIL; ViewerOps.EnumerateViewers[Search]; IF doc # NIL THEN RETURN; GetFromCache[]; }; END. FDocCacheImpl.mesa Mike Spreitzer August 5, 1986 1:11:00 am PDT Κ§– "cedar" style˜code™K™,—K˜KšΟk œœL˜jK˜šΟn œœ˜Kšœœ<˜FKšœ ˜K˜—K˜Kšœœ ˜K˜K˜DK˜oKšœ œœœ˜Kšœ œœ˜Kšœœ˜Kšœ œ˜K˜šžœœœœœœœΟcœ˜OKšœ œ˜K˜ K˜—K˜š ž œœ œœœŸœ˜_Kšœœœœ˜Kšœœœ˜šœœ˜K˜K˜K˜Kšœœ˜—K˜—K˜Kšœœœ˜šœœœ˜Kšœœ˜K˜Kšœœ˜ K˜—K˜š žœœœ œœ˜AKšœœœœ˜)Kš œœœœ(œœœ ˜uš žœœœ œœŸœ˜`šœœœœ˜FK˜*šœœœ˜Kšœœ˜Kšœ œ˜K˜—K˜—K˜—šž œœœ˜šœœ˜Kšœ˜Kšœ˜Kšœ œœ˜—K˜ Kšœœœœ˜DKšœœ#˜-šœœœ˜Kšœ$˜$šœœ˜Kšœ ˜ K˜Kšœœ˜!K˜—šœ˜#Kšœ œ˜,K˜Kšœ%˜%Kšœ˜—Kšœœ œœ˜1K˜K˜—šœ˜K˜ K˜Kšœ˜K˜K˜—Kšœ˜K˜K˜—Kšœœ˜ K˜#Kšœœœœ˜K˜K˜—K˜Kšœ˜—…— D 1