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.