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.