TiogaDocumentsCacheImpl.mesa; Edited by Paxton on June 20, 1983 1:28 pm
Last Edited by: Maxwell, January 6, 1983 11:10 am
Last Edited by: Plass, March 16, 1983 11:59 am
DIRECTORY
Process USING [Detach],
Rope USING [Concat, Equal, ROPE],
TiogaDocumentsCache,
TiogaDocumentPrivate,
TiogaInput USING [FreeTree],
TiogaProfile USING [unsavedDocumentCacheSize],
TiogaNode USING [RefBranchNode];
TiogaDocumentsCacheImpl: CEDAR MONITOR
IMPORTS Process, Rope, TiogaDocumentsCache, TiogaInput, TiogaProfile
EXPORTS TiogaDocumentsCache, TiogaDocumentPrivate =
BEGIN OPEN TiogaDocumentsCache, TiogaDocumentPrivate;
list: LIST OF UnsavedDocumentInfo;
UnsavedDocumentInfo: TYPE = REF UnsavedDocumentInfoRec;
UnsavedDocumentInfoRec: TYPE = RECORD [fileName: ROPE, root: TiogaNode.RefBranchNode];
GetList: PUBLIC ENTRY PROC RETURNS [rope: ROPE] = {
FOR l: LIST OF UnsavedDocumentInfo ← list, l.rest UNTIL l=NIL DO
rope ← Rope.Concat[rope, Rope.Concat["\n", l.first.fileName]];
ENDLOOP };
RecordUnsavedDocument: PUBLIC ENTRY PROC [
fileName: ROPE, root: TiogaNode.RefBranchNode] = {
ENABLE UNWIND => NULL;
Size: PROC RETURNS [size: INTEGER] = {
size ← 0;
IF list=NIL THEN RETURN;
FOR l: LIST OF UnsavedDocumentInfo ← list, l.rest UNTIL l=NIL DO
size ← size+1;
ENDLOOP };
info: UnsavedDocumentInfo;
oldRoot: TiogaNode.RefBranchNode;
IF (oldRoot ← SearchList[fileName]) # NIL THEN -- discard previous entry, if any
TiogaInput.FreeTree[oldRoot];
info ← NEW[UnsavedDocumentInfoRec ← [fileName, root]];
list ← CONS[info, list];
WHILE Size[] > MAX[TiogaProfile.unsavedDocumentCacheSize, 0] DO DiscardOldest[]; ENDLOOP;
TRUSTED {Process.Detach[FORK Update[]] }};
FindUnsavedDocument: PUBLIC ENTRY PROC [fileName: ROPE]
RETURNS [root: TiogaNode.RefBranchNode] = {
ENABLE UNWIND => NULL;
IF (root ← SearchList[fileName]) # NIL THEN TRUSTED {Process.Detach[FORK Update[]] }};
DiscardOldest: PROC = {
IF list=NIL THEN RETURN;
FOR l: LIST OF UnsavedDocumentInfo ← list, l.rest DO
IF l.rest # NIL THEN LOOP; -- spin until get to the oldest entry
TiogaInput.FreeTree[SearchList[l.first.fileName]];
RETURN;
ENDLOOP };
SearchList: PROC [fileName: ROPE]
RETURNS [root: TiogaNode.RefBranchNode] = { -- if find, then remove
prev: LIST OF UnsavedDocumentInfo;
IF list=NIL THEN RETURN [NIL];
IF Rope.Equal[list.first.fileName, fileName, FALSE] THEN {
root ← list.first.root;
list ← list.rest;
RETURN };
prev ← list;
FOR l: LIST OF UnsavedDocumentInfo ← list.rest, l.rest UNTIL l=NIL DO
IF Rope.Equal[l.first.fileName, fileName, FALSE] THEN {
root ← l.first.root;
prev.rest ← l.rest;
RETURN };
prev ← l;
ENDLOOP;
RETURN [NIL] };
END.