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
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.