Adding and deleting NAMES
The browser program named BROWSE.NAMES has demonstrated how it is possible to sort and search an existing data file (in this case, the NAMES file) once a B-tree has been created for it. Because the BUILD program created three B-trees that sort NAMES by ZIP code, company, and last names, the BROWSE.NAMES browser program is able to display the NAMES file sorted those three different ways. However, if the GET.NAMES program is now used to add, change, or delete any names or addresses, the B-tree won't be updated to reflect the change. Therefore, it is necessary for GET.NAMES to adjust the B-TREE file any time an item in the NAMES file is edited.
To add new items to the B-tree, GET.NAMES must call the BTPINS subroutine any time a new item is added to the NAMES file. Similarly, GET.NAMES must call the BTPDEL subroutine whenever an item is dropped from the NAMES file and must be deleted from the B-tree. BTPDEL is the final subroutine in the B-TREE-P package, and like BTPINS, BTPFIND, and BTPSEQ, it never needs to be modified to work with any file:
BTPDEL
001 SUBROUTINE BTPDEL(ROOT,SIZE,BFILE,DFILE,ID,ITEM)
002 CALL BTPKEY(ROOT, ID, ITEM, FK)
003 READ NID FROM BFILE, ROOT ELSE STOP "BTP15"
004 F = 0
005 100 READ N FROM BFILE, NID ELSE STOP "BTP16"
006 L = 0 ; R = N<1>+1
007 IF (R = 1) OR F THEN NXP = 1 ; PS = 1 ELSE
008 LOOP
009 PS = INT((L+R)/2)
010 SID = N<2, PS>
011 IF SID = ID THEN
012 F = 1 ; UID = NID ; UP = PS
013 R = L ; NXP = PS+1
014 END ELSE
015 NXP = PS
016 READ IT FROM DFILE,SID ELSE STOP "BTP17"
017 CALL BTPKEY(ROOT, SID, IT, KEY)
018 IG = (FK > KEY)
019 IF IG THEN L = PS ELSE R = PS
020 END
021 UNTIL (R-L) <= 1 DO REPEAT
022 IF NOT(F) THEN
023 IF IG THEN PS = R ; NXP = PS
024 END
025 END
026 NNID = N<3, NXP>
027 IF NNID # "" THEN
028 NID = NNID
029 GO TO 100
030 END
031 IF NOT(F) THEN CRT "Already deleted!" ; RETURN
032 IF N<2, PS> # ID THEN
033 READ UN FROM BFILE, UID ELSE STOP "BTP18"
034 UN<2, UP> = N<2, 1>
035 WRITE UN ON BFILE, UID
036 PS = 1
037 END
038 N = DELETE(N, 2, PS, 0)
039 N<1> = N<1> - 1
040 200 IF (N<1> < SIZE) AND (N<4> # "") THEN
041 PID = N<4>
042 READ P FROM BFILE, PID ELSE STOP "BTP19"
043 LOCATE(NID, P, 3; PS) ELSE STOP "BTP20"
044 NBID = P<3, PS+1> ; PP = PS
045 NBL = (NBID="")
046 IF NBL THEN NBID = P<3, PS-1> ; PP=PS-1
047 READ NB FROM BFILE, NBID ELSE STOP "BTP21"
048 TK = N<1> + NB<1>
049 IF TK >= (2*SIZE) THEN
050 MC = INT((NB<1>-N<1>)/2)
051 FOR I = 1 TO MC
052 IF NBL THEN
053 NBP = NB<1>
054 NP = 1
055 NBPP = NBP+1
056 NPP = NP
057 END ELSE
058 NP = N<1> + 1
059 NBP = 1
060 NPP = NP + 1
061 NBPP = NBP
062 END
063 N = INSERT(N, 2, NP, 0, P<2, PP>)
064 N<1> = N<1>+1
065 P<2, PP> = NB<2, NBP>
066 NB = DELETE(NB, 2, NBP, 0)
067 NB<1> = NB<1>-1
068 CID = NB<3, NBPP>
069 IF CID # "" THEN
070 N = INSERT(N, 3, NPP, 0, CID)
071 NB = DELETE(NB, 3, NBPP, 0)
072 READ C FROM BFILE, CID ELSE STOP "BTP22"
073 C<4> = NID
074 WRITE C ON BFILE, CID
075 END
076 NEXT I
077 WRITE NB ON BFILE, NBID
078 WRITE P ON BFILE, PID
079 WRITE N ON BFILE, NID
080 END ELSE
081 IF NBL THEN
082 IP = NB<1>+1
083 IPP = IP+1
084 GP = 1
085 END ELSE
086 IP = 1
087 IPP = 1
088 GP = N<1>+1
089 END
090 NB = INSERT(NB, 2, IP, 0, P<2, PP>)
091 NL = (NB<3,1> # "")
092 IF NL THEN
093 CID = N<3, GP>
094 NB = INSERT(NB, 3, IPP, 0, CID)
095 READ C FROM BFILE, CID ELSE STOP "BTP23"
096 C<4> = NBID
097 WRITE C ON BFILE, CID
098 END
099 IF NBL THEN
100 IP = IP+1 ; IPP = IPP+1
101 END
102 FOR I = N<1> TO 1 STEP -1
103 NB = INSERT(NB, 2, IP, 0, N<2, I>)
104 IF NL THEN
105 IF NBL THEN
106 NPP = I+1
107 END ELSE NPP = I
108 CID = N<3, NPP>
109 NB = INSERT(NB, 3, IPP, 0, CID)
110 READ C FROM BFILE, CID ELSE STOP "BTP24"
111 C<4> = NBID
112 WRITE C ON BFILE, CID
113 END
114 NEXT I
115 NB<1> = NB<1> + N<1> + 1
116 WRITE NB ON BFILE, NBID
117 DELETE BFILE, NID
118 P = DELETE(P, 2, PP, 0)
119 P = DELETE(P, 3, PS, 0)
120 P<1> = P<1>-1
121 IF P<1> <= 0 THEN
122 DELETE BFILE, PID
123 WRITE NBID ON BFILE, ROOT
124 NB<4> = ""
125 WRITE NB ON BFILE, NBID
126 END ELSE
127 WRITE P ON BFILE, PID
128 N = P
129 NID = PID
130 GO TO 200
131 END
132 END
133 END ELSE WRITE N ON BFILE, NID
134 RETURN
135 END
Note that BTPDEL uses a LOCATE in line 043 to make an unsorted search for NID in the third attribute of P, setting PS accordingly. The syntax of the LOCATE statement may have to be slightly different for your compiler.
Use the Editor to type in the above code for the BTPDEL subroutine, then compile and catalog the program.
Now use the Editor to modify the GET.NAMES program as shown below (new or changed lines have numbers in [square brackets]), so that it calls BTPINS and BTPDEL any time an item is added, changed, or deleted in the NAMES file:
GET.NAMES
[001]OPEN "B-TREE" TO BFILE ELSE STOP
002 OPEN "NAMES" TO NFILE ELSE STOP
003 LOOP
004 CRT "ID NUMBER":
005 INPUT ID
006 UNTIL ID = "" DO
[007] ON.FILE = 1
[008] READU ITEM FROM NFILE,ID ELSE ON.FILE=0;ITEM=""
[009] OLD.ITEM = ITEM
010 AMC = 1 ; LABEL = "FIRST NAME" ; GOSUB 100
011 AMC = 2 ; LABEL = "LAST NAME" ; GOSUB 100
012 AMC = 3 ; LABEL = "COMPANY" ; GOSUB 100
013 AMC = 4 ; LABEL = "ADDRESS" ; GOSUB 100
014 AMC = 5 ; LABEL = "CITY ST" ; GOSUB 100
015 AMC = 6 ; LABEL = "ZIP CODE" ; GOSUB 100
016 CRT "EXIT, FILE, OR DROP":
017 INPUT COMMAND
[018] LOCK 1 ; BREAK OFF
019 BEGIN CASE
020 CASE COMMAND = "FILE"
[021] IF ON.FILE THEN
[022] CALL BTPDEL("ZIP",5,BFILE,NFILE,ID,OLD.ITEM)
[023] CALL BTPDEL("COMP",5,BFILE,NFILE,ID,OLD.ITEM)
[024] CALL BTPDEL("LNAME",5,BFILE,NFILE,ID,OLD.ITEM)
[025] END
[026] CALL BTPINS("ZIP",5,BFILE,NFILE,ID,ITEM)
[027] CALL BTPINS("COMP",5,BFILE,NFILE,ID,ITEM)
[028] CALL BTPINS("LNAME",5,BFILE,NFILE,ID,ITEM)
029 WRITE ITEM ON NFILE, ID
030 CASE COMMAND = "DROP"
[031] IF ON.FILE THEN
[032] CALL BTPDEL("ZIP",5,BFILE,NFILE,ID,OLD.ITEM)
[033] CALL BTPDEL("COMP",5,BFILE,NFILE,ID,OLD.ITEM)
[034] CALL BTPDEL("LNAME",5,BFILE,NFILE,ID,OLD.ITEM)
[035] END
036 DELETE NFILE, ID
037 CASE 1
[038] CRT "EXITING" ; RELEASE
039 END CASE
[040] BREAK ON ; UNLOCK 1
041 REPEAT
042 STOP
Compile and catalog the new version of GET.NAMES and then execute it to add some new names and addresses to the NAMES file, and to change or delete some existing items. Then use BROWSE.NAMES to examine the NAMES file and the items you edited. Use the Z, C, and L commands in BROWSE.NAMES to verify that all items are still displayed in the correct sort order: by ZIP, by company, and by last name.