DIRECTORY Basics, DocCache, PFS, PFSNames, SymTab, RedBlackTree, Rope, TiogaIO, TiogaOps, ViewerClasses, ViewerOps; DocCacheImpl: CEDAR MONITOR IMPORTS PFS, PFSNames, SymTab, RedBlackTree, Rope, TiogaIO, TiogaOps, ViewerOps EXPORTS DocCache = BEGIN OPEN DocCache; byRef: RedBlackTree.Table = RedBlackTree.Create[GetRef, CompareRef]; byName: SymTab.Ref = SymTab.Create[case: FALSE]; 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] = { fullFileName: ROPE; --for debugging, until Cirio can read PFS.PATHs fullPath: PFS.PATH; short: PFSNames.Component; 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].val]; IF e = NIL THEN { doc ¬ TiogaIO.FromFile[PFS.PathFromRope[fullFileName] ! TiogaIO.Error, PFS.Error => CONTINUE].root; IF doc=NIL THEN RETURN; 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; {ENABLE PFS.Error => {doc ¬ NIL; CONTINUE}; fullPath ¬ PFS.AbsoluteName[PFS.PathFromRope[fileName]]; short ¬ fullPath.ShortName[]; IF short.version = [none] THEN fullPath ¬ PFS.FileInfo[fullPath].fullFName; fullFileName ¬ PFS.RopeFromPath[fullPath]; ViewerOps.EnumerateViewers[Search]; IF doc # NIL THEN RETURN; GetFromCache[]; }}; END. ¨DocCacheImpl.mesa Copyright Σ 1990, 1992 by Xerox Corporation. All rights reserved. Mike Spreitzer July 27, 1990 9:22 am PDT Willie-s, April 3, 1992 5:44 pm PST Κ•NewlineDelimiter –(cedarcode) style˜code™Kšœ Οeœ7™BK™(K™#—K˜KšΟk œžœT˜sK˜šΟn œžœž˜KšžœžœD˜OKšžœ ˜K˜—K˜Kšžœžœ ˜K˜K˜DKšœ)žœ˜0Kšœ žœžœžœ˜Kšœ žœžœ˜Kšœžœ˜Kšœ žœ˜K˜šŸœžœžœžœžœžœžœΟcœ˜OKšœ žœ˜K˜ K˜—K˜š Ÿ œžœ žœžœžœ œ˜_Kšœžœžœžœ˜Kšœžœžœ˜šœžœž˜K˜K˜K˜Kšžœžœ˜—K˜—K˜Kšœžœžœ˜šœžœžœ˜Kšœžœ˜K˜Kšœžœž˜ K˜—K˜š Ÿœžœžœ žœžœ˜AKšœžœ /˜CKšœ žœžœ˜K˜š Ÿœžœžœ žœžœ œ˜`šžœžœžœžœ˜FK˜*šžœžœžœ˜Kšžœžœ˜Kšœ žœ˜K˜—K˜—K˜—šŸ œžœžœ˜šžœžœ˜Kšœ˜Kšœ˜Kšœ žœžœ˜—K˜ Kšžœžœžœžœ˜DKšœžœ!˜+šžœžœžœ˜Kšœžœ-žœ žœ˜cKšžœžœžœžœ˜šœžœ˜Kšœ ˜ K˜Kšžœžœ˜!K˜—šžœž˜#Kšœ žœ˜,K˜K˜%Kšžœ˜—Kšžœžœ žœžœ˜1K˜K˜—šžœ˜K˜ K˜K˜K˜K˜—K˜K˜K˜—Kšœžœ˜ Kš œžœžœžœžœ˜+Kšœ žœžœ˜8K˜Kšžœžœ žœ˜KKšœžœ˜*K˜#Kšžœžœžœžœ˜K˜K˜—K˜Kšžœ˜—…— :ύ