!TITLE Procedures for manipulating Name-Number Tables !DUMPNNT lists the entries that are in use ! !CLEARNNT sets a NNT to zero. It can (will) be re-created ! automatically at the next CCK ! !STATUSNNT analyses a NNT and computes a histogram of the path ! lengths to reach each name ! !OPTNNT saves the current NNT in a file N#NTf where f is the ! fsys number. Re-orders the entries in an optimum way ! !RESTORENNT returns the contents N#NTf to the NNT !> RECORDFORMAT NNF(STRING (6) USER, BYTEINTEGER KB, TAG, MARKER, HALFINTEGER INDNO) CONSTINTEGER NNTTOP= 1364 OWNRECORD (NNF) ARRAY NEWNNT(0:NNTTOP) OWNRECORD (NNF) ARRAYFORMAT NNAF(0:NNTTOP) CONSTSTRING (5)TFILE = "N#NT" ! RECORDFORMAT DATAF(INTEGER START, BITSIZE, NNTSTART, NNTSIZE, NNTTOP, NNTHASH, INDEXSTART, FILESTART, END) RECORDFORMAT FF(INTEGER SD, PD, FD, S, S1, S2, SNO, RESTORES, STRING (6)OWNER, BYTEINTEGER SIZE, STRING (11)NAME) ! ! ! EXTERNALSTRINGFNSPEC DERRS(INTEGER N) ! %EXTERNALINTEGERFNSPEC DERROR(%STRINGNAME TXT) EXTERNALINTEGERFNSPEC DLOWERACR(INTEGER ACR) EXTERNALINTEGERFNSPEC DBITMAP2(INTEGERNAME LO, HI, INTEGER FSYS) EXTERNALINTEGERFNSPEC DNINDA(INTEGER FSYS, INDNO, INTEGERNAME INDAD) EXTERNALINTEGERFNSPEC FBASE(INTEGERNAME LO, HI, INTEGER FSYS) SYSTEMSTRINGFNSPEC HTOS(INTEGER VALUE, PALCES) SYSTEMSTRINGFNSPEC ITOS(INTEGER I) EXTERNALROUTINESPEC PROMPT(STRING (15) S) EXTERNALSTRINGFNSPEC DATE EXTERNALSTRINGFNSPEC TIME INTEGERFN STOI2(STRING (255) S, INTEGERNAME I2) STRING (63) P INTEGER TOTAL, SIGN, AD, I, J, HEX !MON MON(1) = MON(1) + 1 HEX = 0; TOTAL = 0; SIGN = 1 AD = ADDR(P) A: IF S -> (" ").S THEN -> A; !CHOP LEADING SPACES IF S -> ("-").S THEN SIGN = -1 IF S -> ("X").S THEN HEX = 1 AND -> A P = S UNLESS S -> P.(" ").S THEN S = "" I = 1 WHILE I <= BYTEINTEGER(AD) CYCLE J = BYTE INTEGER(I+AD) -> FAULT UNLESS '0' <= J <= '9' OR (HEX # 0 C AND 'A' <= J <= 'F') IF HEX = 0 THEN TOTAL = 10*TOTAL C ELSE TOTAL = TOTAL<<4+9*J>>6 TOTAL = TOTAL+J&15; I = I+1 REPEAT IF HEX # 0 AND I > 9 THEN -> FAULT IF I > 1 THEN I2 = SIGN*TOTAL AND RESULT = 0 FAULT: I2 = 0 RESULT = 1 END ; ! STOI2 ! !----------------------------------------------------------------------- ! !----------------------------------------------------------------------- ! ! ! ROUTINE RSTRG(STRINGNAME S) INTEGER I S = "" CYCLE READSYMBOL(I) RETURN IF I = NL S = S . TOSTRING(I) REPEAT END ! ! ! ROUTINE RDINT(INTEGERNAME N) STRING (63)S N = -1 CYCLE RSTRG(S) RETURN IF STOI2(S, N) = 0 REPEAT END ! EXTERNALINTEGERFNSPEC DDISCONNECT(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, DESTROY) EXTERNALINTEGERFNSPEC DCONNECT(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, MODE, APF, INTEGERNAME SEG, GAP) EXTERNALINTEGERFNSPEC DCREATE(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, NKB, TYPE) SYSTEMROUTINESPEC MOVE(INTEGER LEN, FROM, TO) SYSTEMROUTINESPEC FILL(INTEGER LEN, FROM, PATTERN) ! ! ! ROUTINE WS(STRING (255) S) PRINTSTRING(S) NEWLINE END ; ! WS ! ! ! ROUTINE WSN(STRING (255)S, INTEGER N) PRINTSTRING(S) WRITE(N, 1) NEWLINE END ; ! WSN ! ! ! INTEGERFN FBASE2(INTEGER FSYS, ADR) ! ! This returns the characteristics of an on-line disc in a record ! of format DISCDATAF at address ADR INTEGER J, LOB, HIB, TYPE, K RECORD (DATAF) NAME DATA CONSTINTEGER TOPTYPE= 5 CONSTINTEGERARRAY BITSIZE(1:TOP TYPE)= X'1000'(2), X'2000'(2), X'5000' CONSTINTEGERARRAY NNTSTART(1:TOP TYPE)= X'7000'(4), X'A000' CONSTINTEGERARRAY NNTSIZE(1:TOP TYPE)= X'4000'(4), X'1FF8' CONSTINTEGERARRAY NNTTOP(1:TOP TYPE)= 1364(4), 681 CONSTINTEGERARRAY NNTHASH(1:TOP TYPE)= 1361(4), 667 CONSTBYTEARRAY INDEXSTART(1:TOP TYPE)= 12(5) CONSTINTEGERARRAY FILESTART(1:TOP TYPE)= 1024(5) CONSTINTEGERARRAY HI(1:TOP TYPE)= X'3F1F', X'59F3', X'8F6F', X'B3E7', X'24797' J = FBASE(LOB, HIB, FSYS) RESULT = J UNLESS J = 0 ! TYPE = - 1 CYCLE K = 1, 1, TOP TYPE TYPE = K ANDEXITIF HIB = HI(K) REPEAT RESULT = 8 IF TYPE < 0 ! DATA == RECORD(ADR) ! DATA_START = LOB DATA_BITSIZE = BITSIZE(TYPE) DATA_NNTSTART = NNTSTART(TYPE) DATA_NNTSIZE = NNTSIZE(TYPE) DATA_NNTTOP = NNTTOP(TYPE) DATA_NNTHASH = NNTHASH(TYPE) DATA_INDEXSTART = INDEX START(TYPE) DATA_FILESTART = FILE START(TYPE) DATA_END = HIB RESULT = 0 END ; ! FBASE2 ! !----------------------------------------------------------------------- ! INTEGERFN HASH(STRING (6) USER, INTEGER NNTHASH) INTEGER A, J, W CONSTINTEGERARRAY P(1:6)=157,257,367,599, 467,709 A = ADDR(USER) W = 0 CYCLE J = 1, 1, 6 W = W + (BYTEINTEGER(A + J) - 47) * P(J) REPEAT RESULT = W - (W // NNTHASH) * NNTHASH END ; ! HASH ! ! ! INTEGERFN INIT(INTEGERNAME FSYS, ANNT, RECORD (DATAF)NAME DATA) INTEGER FLAG, LO, HI PROMPT("Which FSYS? ") RDINT(FSYS) ! FLAG = FBASE2(FSYS, ADDR(DATA)); ! get characteristics of disc ->FAIL UNLESS FLAG = 0 ! FLAG = DBITMAP2(LO, HI, FSYS) -> FAIL UNLESS FLAG = 0 ANNT = LO >> 18 << 18 + DATA_NNTSTART FAIL: RESULT = FLAG END ; ! INIT ! ! ! EXTERNALROUTINE DUMPNNT(STRING (255)S) INTEGER FLAG, FSYS, ANNT, J RECORD (DATAF)DATA RECORD (NNF)ARRAYNAME NNT FLAG = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS FLAG = 0 ! NNT == ARRAY(ANNT, NNAF) ! CYCLE J = 0, 1, DATA_NNTTOP IF LENGTH(NNT(J)_USER) = 6 START WRITE(J, 4) SPACE PRINTSTRING(NNT(J)_USER) WRITE(NNT(J)_KB, 3) WRITE(NNT(J)_INDNO, 5) PRINTSTRING(" (file index)") UNLESS NNT(J)_TAG = 0 NEWLINE FINISH REPEAT FAIL: WS(DERRS(FLAG)) END ; ! DUMPNNT ! ! ! EXTERNALROUTINE OPTNNT(STRING (255) S) INTEGER FLAG, I, NUSERS, PATH, NEWI, A, NNTTOP, ANNT, NNTHASH INTEGER FSYS, SEG, GAP RECORD (DATAF) DATA RECORD (NNF) ARRAY AUX(0:1364) RECORD (NNF) ARRAYNAME OLDNNT STRING (11)FILE A = 0; ! POSITION ON AUXTAB NUSERS = 0 PATH = 0 ! FLAG = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS FLAG = 0 ! FILE = TFILE . ITOS(FSYS) NNTTOP = DATA_NNTTOP NNTHASH = DATA_NNTHASH CYCLE I = 0, 1, NNTTOP; ! clear own array NEWNNT(I) = 0 REPEAT ! ! FLAG = DCREATE("", FILE, -1, 20, 0); ! big enough for a 4-page NNT and hdr -> FAIL UNLESS FLAG = 0 ! SEG = 0 GAP = 0 FLAG = DCONNECT("", FILE, -1, 3, 0, SEG, GAP) -> FAIL UNLESS FLAG = 0 ! OLDNNT == ARRAY(SEG<<18 + 4096, NNAF) ! MOVE(DATA_NNTSIZE, ANNT, ADDR(OLDNNT(0))) ! CYCLE I = 0, 1, NNTTOP IF LENGTH(OLDNNT(I)_USER) = 6 START NUSERS = NUSERS + 1 NEWI = HASH(OLDNNT(I)_USER, NNTHASH) IF NEWNNT(NEWI)_USER = "" C THEN NEWNNT(NEWI) = OLDNNT(I) C ELSESTART AUX(A) = OLDNNT(I) A = A + 1 FINISH FINISH REPEAT ! FLAG = DDISCONNECT("", FILE, -1, 0) -> FAIL UNLESS FLAG = 0 ! WSN("No of users:", NUSERS) WSN("No of clashes:", A) ! WHILE A > 0 CYCLE A = A - 1 NEWI = HASH(AUX(A)_USER, NNTHASH) CYCLE PATH = PATH + 1 NEWI = NEWI + 1 NEWI = 0 IF NEWI > NNTTOP IF NEWNNT(NEWI)_USER = "" C THEN NEWNNT(NEWI) = AUX(A) AND EXIT REPEAT REPEAT WSN("Path length:", PATH) ! FLAG = D LOWER ACR(2) -> FAIL UNLESS FLAG = 0 ! MOVE(DATA_NNTSIZE, ADDR(NEWNNT(0)), ANNT) FAIL: ! J = DERROR(TXT) WS(DERRS(FLAG)) END ; ! OPTNNT ! ! ! EXTERNALROUTINE RESTORE NNT(STRING (255)S) INTEGER FLAG, FSYS, ANNT, SEG, GAP, J STRING (11)FILE RECORD (DATAF)DATA FLAG = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS FLAG = 0 ! SEG = 0 GAP = 0 FILE = TFILE . ITOS(FSYS) FLAG = DCONNECT("", FILE, -1, 1, 0, SEG, GAP) -> FAIL UNLESS FLAG = 0 ! FLAG = DLOWERACR(2) -> FAIL UNLESS FLAG = 0 ! MOVE(DATA_NNTSIZE, SEG<<18 + 4096, ANNT) FAIL: J = DDISCONNECT("", FILE, -1, 0) WS(DERRS(FLAG)) END ; ! RESTORE NNT ! ! ! EXTERNALROUTINE CLEAR NNT(STRING (255)S) INTEGER FLAG, FSYS, ANNT RECORD (DATAF)DATA FLAG = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS FLAG = 0 ! FLAG = DLOWERACR(2) -> FAIL UNLESS FLAG = 0 ! FILL(DATA_NNTSIZE, ANNT, 0) FAIL: WS(DERRS(FLAG)) END ; ! CLEAR NNT ! ! ! EXTERNALROUTINE STATUSNNT(STRING (255) S) INTEGER ANNT, NUSERS, P RECORD (NNF) NAME NN RECORD (NNF) ARRAYNAME NNT INTEGER FLAG, I, J INTEGER FSYS, PATH INTEGERARRAY HISTO(0:8) RECORD (DATAF) DATA WS("STATUS at ".TIME." on ".DATE) NUSERS = 0 PATH = 0 CYCLE J = 0, 1, 8 HISTO(J) = 0 REPEAT ! FLAG = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS FLAG = 0 ! NNT == ARRAY(ANNT, NNAF) ! CYCLE J = 0, 1, DATA_NNTTOP NN == NNT(J) IF LENGTH(NN_USER) = 6 START NUSERS = NUSERS + 1 P = J - HASH(NN_USER, DATA_NNTHASH) P = P + DATA_NNTTOP IF P < 0 PATH = PATH + P ! HISTO(P) = HISTO(P) + 1 IF P <= 5 HISTO(6) = HISTO(6) + 1 IF 6 <= P <= 10 HISTO(7) = HISTO(7) + 1 IF 11 <= P <= 20 HISTO(8) = HISTO(8) + 1 IF P > 20 FINISH REPEAT WSN("No of users :", NUSERS) WSN("Total path :", PATH) PRINTSTRING("Average path:") PRINT(PATH/NUSERS, 3, 2) NEWLINE WS("Path length histogram") WS(" 0 1 2 3 4 5 6-10 11-20 >20") CYCLE I = 0, 1, 8 WRITE(HISTO(I), 6) REPEAT NEWLINE FAIL: WS(DERRS(FLAG)) END ; ! STATUSNNT ! ! ! EXTERNALROUTINE CLEAR EXTRA INDEX(STRING (255)S) INTEGER J, FSYS, ANNT, INDNO, HI, P, INDAD RECORD (DATAF)DATA J = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS J = 0 ! INDNO = 256 << 2; ! first 1K after 'old' indexes HI = DATA_FILESTART << 2 - 1; ! last J = DLOWERACR(2) -> FAIL UNLESS J = 0 CYCLE P = INDNO, 1, HI J = DNINDA(FSYS, P, INDAD) -> FAIL UNLESS J = 0 FILL(1024, INDAD, 0) STRING(INDAD) = "NEVER" REPEAT FAIL: WS(DERRS(J)) END ; ! CLEAR EXTRA INDEX ! ! ! EXTERNALROUTINE CHECK EXTRA INDEX(STRING (255)S) INTEGER J, FSYS, ANNT, INDNO, HI, P, K, INDAD, C RECORD (DATAF)DATA RECORD (FF)NAME F J = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS J = 0 ! INDNO = 256 << 2 HI = DATA_FILESTART << 2 -1 C = 0 CYCLE P = INDNO, 1, HI J = DNINDA(FSYS, P, INDAD) -> FAIL UNLESS J = 0 F == RECORD(INDAD) IF LENGTH(F_OWNER) = 6 AND 0 < LENGTH(F_NAME) < 12 START C = C + 1 RETURN IF C > 20 PRINTSTRING(HTOS(P<<2+K, 3)) SPACE PRINTSTRING(F_OWNER . " " . F_NAME . " ") FINISH REPEAT FAIL: WS(DERRS(J)) END ; ! CHECK EXTRA INDEX ! ! ! EXTERNALROUTINE WRITE NEVERS(STRING (255)S) INTEGER J, FSYS, ANNT, LO, HI, P, INDAD RECORD (DATAF)DATA J = INIT(FSYS, ANNT, DATA) -> FAIL UNLESS J = 0 ! LO = 12 << 2 HI = 256 << 2 - 2 ! J = DLOWERACR(2) -> FAIL UNLESS J = 0 ! CYCLE P = HI, -2, LO J = DNINDA(FSYS, P, INDAD) -> FAIL UNLESS J = 0 UNLESS STRING(INDAD) = "EMPTY" START WSN("LAST NON EMPTY", P) EXIT FINISH STRING(INDAD) = "NEVER" REPEAT FAIL: WS(DERRS(J)) END ; ! WRITE NEVERS ENDOFFILE