The BTPINS subroutine is used to add item identifiers to B-trees, and the BTPDEL subroutine deletes item identifiers from B-trees. The BUILD program was the first example that showed how BTPINS is called:
BUILD 001 OPEN "B-TREE" TO BFILE ELSE STOP 002 OPEN "NAMES" TO NFILE ELSE STOP 003 SELECT NFILE 004 100 READNEXT ID ELSE STOP 005 READ ITEM FROM NFILE, ID ELSE STOP 006 CALL BTPINS("ZIP", 5, BFILE, NFILE, ID, ITEM) 007 CALL BTPINS("COMP", 5, BFILE, NFILE, ID, ITEM) 008 CALL BTPINS("LNAME", 5, BFILE, NFILE, ID, ITEM) 009 GO TO 100 010 END
BTPINS is called with six arguments. The first argument can be a constant or variable, and is the name of the B-tree into which the item identifier is being inserted.
The second constant or variable argument is the B-tree's node size, which has been described earlier. This argument can have a different value for each B-tree, but once it is set for a given B-tree, it can never change until the B-tree is completely empty or cleared. 50 is a recommended node size for general B-TREE-P use.
The third argument is the file variable the B-tree file was opened to in a previous OPEN statement.
The fourth argument is the file variable for a data file opened in a previous OPEN statement.
The fifth constant or variable argument is a data file item identifier being inserted in the B-tree.
The sixth and final constant or variable argument is the data belonging to the item identifier being inserted in the B-tree.
BTPDEL requires exactly the same arguments as BTPINS, but simply performs the reverse operation of removing an item identifier from a B-tree instead of inserting it.
BTPINS and BTPDEL have to be called from any program that creates, changes, or deletes data items in a file, if a B-tree is being maintained for that data. That was demonstrated in the final version of the GET.NAMES example:
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
Notice in the above example that when a newly created item is written into the NAMES file for the first time, the program calls BTPINS for each of the three B-trees that sort the item. The ON.FILE variable is used to detect whether the item being edited is already on file or not. If an existing item is being rewritten into the file, BTPDEL is called first to remove the item's old position in the B-tree, and BTPINS is then called to insert the item back in. (That's because if the user edited any fields, the item's position in one or more B-trees might no longer be correct. A more efficient version of GET.NAMES would only delete and reinsert items into a B-tree if the fields used by BTPKEY for that B-tree have changed. For example, an item has to be deleted and reinserted in the LNAME B-tree only if it's first or last name changed, since item identifiers in the LNAME B-tree don't move when company names or addresses are changed.)
If an item exists and is being deleted from the NAMES file, GET.NAMES is careful to call BTPDEL, using the old original item as it last existed when inserted in the B-tree, not the item the user may have edited but never filed just before giving the DROP command.
To prevent GET.NAMES from terminating after the B-trees have been adjusted, but before the item is written or deleted in the NAMES file, the break key is temporarily disabled during the critical section of code. Also, a LOCK is used any time BTPINS or BTPDEL are executing, to prevent other users of the same B-trees from attempting simultaneous updates that may leave the B-trees in an inconsistent state.