VersionMap2AsHintImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on April 10, 1992 9:35 am PDT
DIRECTORY IO, PFS, PFSNames, Rope, VersionMap2, VersionMap2AsHint, VersionMap2Implr, VersionMapClassify;
VersionMap2AsHintImpl: CEDAR PROGRAM
IMPORTS PFS, PFSNames, VersionMap2, VersionMap2Implr, VersionMapClassify
= {OPEN PVMC:VersionMapClassify, VersionMap2;
HinterMap: TYPE ~ REF HinterMapPrivate;
HinterMapPrivate: TYPE ~ RECORD [
base, cache, hints: Map,
theStamp: VersionStamp,
sg, cg, hg: BOOL
];
hmClass: MapClass ~ VersionMap2Implr.FillinDefaults[FALSE, readonly, [
Scan: HmScan,
data: NIL]];
CreateHintTaker: PUBLIC PROC [base: Map, theStamp: VersionStamp ← nullStamp, cache, hints: Map ← nullMap] RETURNS [Map] ~ {
hm: HinterMap ~ NEW [HinterMapPrivate ← [base, cache, hints, theStamp, theStamp#nullStamp, cache#nullMap, hints#nullMap]];
RETURN [[hmClass, hm]]};
HmScan: PROC [map: Map, Consume: TupleConsumer, inOrder: BOOL, pfml: PatternFactoredMapList] RETURNS [MaybeTuple] ~ {
hm: HinterMap ~ NARROW[map.data];
IF pfml.stampInd=listOfEmpty THEN RETURN [noMaybe];
IF hm.sg AND NOT StampMatch[hm.theStamp, pfml.pattern.stamp] THEN RETURN [noMaybe];
{tried: Map ~ IF NOT inOrder THEN CreateVariableMap[] ELSE nullMap;
lastTried: Name ← nullName;
mt: MaybeTuple ← noMaybe;
PerTuple: PROC [bt: VersionTuple] RETURNS [BOOL] ~ {
thisTry: Name ~ VaguifyName[bt.name];
PerInfo: PROC [fullFName, attachedTo: Name, uniqueID: Created, bytes: INT, mutability: PFS.Mutability, fileType: PFS.FileType] RETURNS [continue: BOOLTRUE] --PFS.InfoProc-- ~ {
IF NOT NameMatch[fullFName, pfml.pattern.name] THEN RETURN [TRUE];
IF NOT CreatedMatch[uniqueID, pfml.pattern.created] THEN RETURN [TRUE];
IF pfml.stampInd#NIL AND NOT AllHave[pfml.stampInd, [fullFName, uniqueID]] THEN RETURN [TRUE];
IF hm.sg THEN mt.it ← [fullFName, uniqueID, hm.theStamp]
ELSE {
thisLC: PFSNames.Component ~ fullFName.ShortName[];
seek: VersionTuple ~ [LastComponentToPattern[[name: thisLC.name, version: [all]]].name, uniqueID, nullStamp];
mt ← noMaybe;
IF hm.cg THEN mt ← hm.cache.ScanMatches[AlwaysAccept, FALSE, seek];
IF hm.hg AND NOT mt.found THEN mt ← hm.hints.ScanMatches[AlwaysAccept, FALSE, seek];
IF NOT mt.found THEN {
nameR: ROPE ~ PFS.RopeFromPath[fullFName];
kind: PVMC.Kind ~ PVMC.Classify[nameR];
mt.it ← [fullFName, uniqueID, PVMC.ReadVersionStamp[kind, nameR, uniqueID.egmt.gmt, FALSE].stamp];
IF hm.cg THEN [] ← hm.cache.AddTuple[mt.it]};
IF NOT StampMatch[mt.it.stamp, pfml.pattern.stamp] THEN {mt.found ← FALSE; RETURN [TRUE]};
};
IF pfml.general#NIL AND NOT AllHave[pfml.general, mt.it] THEN {mt.found ← FALSE; RETURN [TRUE]};
IF Consume[mt.it] THEN {mt.found ← TRUE; RETURN [FALSE]};
mt.found ← FALSE; RETURN [TRUE]};
IF inOrder THEN {
IF NameEqual[lastTried, thisTry] THEN RETURN [mt.found];
lastTried ← thisTry}
ELSE IF tried.AddTuple[[PFSNames.SetVersionNumber[bt.name, [none]]] ].had[created] # none THEN RETURN [mt.found];
IF pfml.pattern.created # nullCreated THEN {
full, attached: Name;
uniqe: Created;
bytes: INT;
mut: PFS.Mutability;
ft: PFS.FileType;
[full, attached, uniqe, bytes, mut, ft] ← PFS.FileInfo[bt.name, pfml.pattern.created !PFS.Error => GOTO NotFound];
IF bytes>=0 THEN [] ← PerInfo[full, attached, uniqe, bytes, mut, ft];
EXITS NotFound => mt.found ← FALSE}
ELSE {
hbound: Name ← NIL;
IF NOT inOrder THEN {
attached: Name;
uniqe: Created;
bytes: INT;
mut: PFS.Mutability;
ft: PFS.FileType;
[hbound, attached, uniqe, bytes, mut, ft] ← PFS.FileInfo[PFSNames.SetVersionNumber[bt.name, [highest]] !PFS.Error => GOTO NotFound];
IF bytes>=0 THEN [] ← PerInfo[hbound, attached, uniqe, bytes, mut, ft];
IF mt.found THEN RETURN [TRUE];
EXITS NotFound => mt.found ← FALSE};
PFS.EnumerateForInfo[thisTry, PerInfo, NIL, hbound]};
RETURN [mt.found]};
[] ← hm.base.ScanMatches[PerTuple, inOrder, [VaguifyName[pfml.pattern.name]]];
RETURN [mt]}};
VaguifyName: PROC [name: Name] RETURNS [Name] ~ {
RETURN PFSNames.SetVersionNumber[name, [all]]};
}.