How to use BTPINS and BTPDEL
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.