PGSupportImpl.Mesa
Written by Bill Paxton, January 1981
last written by Paxton. June 10, 1983 2:18 pm
Last Edited by: Lamming, February 14, 1983 4:45 pm
DIRECTORY
PGSupport,
FileOps,
T2FileOps,
NameSymbolTable,
NodeProps,
TiogaLooks,
TiogaLooksOps,
Inline,
Rope;
PGSupportImpl:
CEDAR MONITOR
IMPORTS Inline, NodeProps
EXPORTS PGSupport
SHARES PGSupport =
BEGIN
OPEN PGSupport;
-- PGF is the file-level structure for put/get
prefixAtom: ATOM = NodeProps.PrefixAtom[];
postfixAtom: ATOM = NodeProps.PostfixAtom[];
CreatePGF:
PUBLIC
PROC
RETURNS [pgf:
PGF] = {
pgf ← AllocPGF[];
pgf.looksTable[0] ← TiogaLooks.noLooks;
pgf.looksNext ← 1; -- reserve 0 for noLooks
FOR i:LooksHashIndex
IN LooksHashIndex
DO
pgf.looksHashKeys[i].looks ← TiogaLooks.noLooks; ENDLOOP;
pgf.typeTable[0] ← NameSymbolTable.nullName;
FOR i:TypeHashIndex
IN TypeHashIndex
DO
pgf.typeHashKeys[i].typename ← NameSymbolTable.nullName; ENDLOOP;
pgf.typeNext ← 1; -- reserve 0 for null typename
pgf.propNext ← 1; --reserve 0 for NIL
FOR i:PropHashIndex
IN PropHashIndex
DO
pgf.propHashKeys[i].propname ← NIL; ENDLOOP;
[] ← EnterProp[prefixAtom, pgf]; -- preload system atoms
[] ← EnterProp[postfixAtom, pgf];
};
pgf1, pgf2, pgf3: PGF ← NIL;
AllocPGF:
ENTRY PROC
RETURNS [pgf:
PGF] = {
ENABLE UNWIND => NULL;
IF pgf3 # NIL THEN { pgf ← pgf3; pgf3 ← NIL }
ELSE IF pgf2 # NIL THEN { pgf ← pgf2; pgf2 ← NIL }
ELSE IF pgf1 # NIL THEN { pgf ← pgf1; pgf1 ← NIL }
ELSE pgf ← NEW[PGFBody] };
FreePGF:
PUBLIC
ENTRY
PROC [pgf:
PGF] = {
ENABLE UNWIND => NULL;
IF pgf3 = pgf OR pgf2 = pgf OR pgf1 = pgf THEN ERROR;
IF pgf3 = NIL THEN pgf3 ← pgf
ELSE IF pgf2 = NIL THEN pgf2 ← pgf
ELSE IF pgf1 = NIL THEN pgf1 ← pgf };
EnterTypeName:
PUBLIC
PROC
[typename: NameSymbolTable.Name, pgf: PGF]
RETURNS [ok: BOOLEAN, index: FileOps.TypeIndex] = {
next: NAT ← pgf.typeNext;
initloc, loc: NAT;
IF typename = NameSymbolTable.nullName THEN RETURN [TRUE, 0]; -- reserved
loc ← initloc ← LOOPHOLE[typename,NAT] MOD typeHashSize;
DO
SELECT pgf.typeHashKeys[loc].typename
FROM
typename => RETURN [TRUE, pgf.typeHashVals[loc].index];
NameSymbolTable.nullName => EXIT; -- this is an unused entry
ENDCASE;
SELECT (loc ← loc+1)
FROM
typeHashSize => IF (loc ← 0)=initloc THEN ERROR;
initloc => ERROR; -- should never have full table
ENDCASE;
ENDLOOP;
IF next < FileOps.numTypes
THEN
-- room left in table
BEGIN
pgf.typeTable[next] ← typename;
pgf.typeNext ← next+1;
pgf.typeHashKeys[loc].typename ← typename;
pgf.typeHashVals[loc].index ← LOOPHOLE[next];
END;
RETURN [FALSE, 0] }; -- index irrelevant in this case
EnterLooks:
PUBLIC
PROC [looks: TiogaLooks.Looks, pgf:
PGF]
RETURNS [ok: BOOLEAN, index: T2FileOps.LooksIndex] = {
next: NAT ← pgf.looksNext;
initloc, loc: NAT;
IF looks = TiogaLooks.noLooks THEN RETURN [TRUE, 0]; -- reserved
loc ← initloc ←
LOOPHOLE[
Inline.
BITXOR[
LOOPHOLE[looks, TiogaLooksOps.LooksBytes].byte0,
Inline.
BITXOR[
LOOPHOLE[looks, TiogaLooksOps.LooksBytes].byte1,
LOOPHOLE[looks, TiogaLooksOps.LooksBytes].byte2]],NAT]
MOD looksHashSize;
DO
SELECT pgf.looksHashKeys[loc].looks
FROM
looks => RETURN [TRUE, pgf.looksHashVals[loc].index];
TiogaLooks.noLooks => EXIT; -- this is an unused entry
ENDCASE;
SELECT (loc ← loc+1)
FROM
looksHashSize => IF (loc ← 0)=initloc THEN ERROR;
initloc => ERROR; -- should never have full table
ENDCASE;
ENDLOOP;
IF next < FileOps.numLooks
THEN
-- room left in table
BEGIN
pgf.looksTable[next] ← looks;
pgf.looksNext ← next+1;
pgf.looksHashKeys[loc].looks ← looks;
pgf.looksHashVals[loc].index ← LOOPHOLE[next];
END;
RETURN [FALSE, 0] }; -- index irrelevant in this case
EnterProp:
PUBLIC
PROC [propname:
ATOM, pgf:
PGF]
RETURNS [ok: BOOLEAN, index: FileOps.PropIndex] = {
next: NAT ← pgf.propNext;
initloc, loc: NAT;
IF propname = NIL THEN RETURN [TRUE, 0]; -- reserved
loc ← initloc ← (LOOPHOLE[Inline.LowHalf[propname],NAT] / 16) MOD propHashSize;
DO
SELECT pgf.propHashKeys[loc].propname
FROM
propname => RETURN [TRUE, pgf.propHashVals[loc].index];
NIL => EXIT; -- this is an unused entry
ENDCASE;
SELECT (loc ← loc+1)
FROM
propHashSize => IF (loc ← 0)=initloc THEN ERROR;
initloc => ERROR; -- should never have full table
ENDCASE;
ENDLOOP;
IF next < FileOps.numProps
THEN
-- room left in table
BEGIN
pgf.propTable[next] ← propname;
pgf.propNext ← next+1;
pgf.propHashKeys[loc].propname ← propname;
pgf.propHashVals[loc].index ← LOOPHOLE[next];
END;
RETURN [FALSE, 0] }; -- index irrelevant in this case
-- ***** Initialization
Start:
PUBLIC
PROC = {
};
END.