As an example of how multivalued B-trees are created, let's assume the items in the NAMES file from BTP/Branches #1 not only have names and addresses in attributes 1 to 6, but also that attribute 7 is a multivalued list of "payment dates". If you want to create a B-tree called DATES that indexes every occurrence of a payment date, then you must call BTPINS once for every payment date in every record. This can be done with a program similar to the original BUILD example in BTP/Branches #1:
BUILD.DATES 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 V = 1 007 LOOP 008 DATE = ITEM<7,V> 009 UNTIL DATE = "" DO 010 CALL BTPINS("DATES",5,BFILE,NFILE,ID:"*":V,ITEM) 011 V = V+1 012 REPEAT 013 GO TO 100 014 END
Notice how the LOOP in BUILD.DATES calls BTPINS once for every multivalue payment date in attribute 7 for every record, being careful to append the multivalue's position number to ID, using an asterisk as an arbitrary delimiter between the two. (Only the relative multivalue number of a payment date, not the actual date itself, is used in the CALL statement.) As a result, a B-tree is created that contains pairs of item identifiers and multivalue numbers separated by asterisks, instead of just the item identifiers alone. This allows item identifiers to be stored in the B-tree any number of times, once for each multivalue, thereby providing an "exploded" list of all records sorted by payment date.
Notice that the LOOP only calls BTPINS if a date is present, so null multivalues are ignored. In general, it's a good idea to not create a B-tree entry for null data (whether single or multivalued), since it just wastes time and space to index empty fields. Skipping null data is a particularly good way to save space and keep B-trees small when indexing files like name and address lists, where company names are often missing. (Note that BUILD.DATES assumes a null indicates the end of the multivalued list. For files where the multivalued list can include imbedded null values, a different end-of-list test will be necessary to insure BTPINS is called once for every multivalue in the list.)
The use of an asterisk as the arbitrary delimiter is simply a standard Pick programming technique for concatenating strings that must be split again later. If your data file's item identifiers already include asterisks, some other delimiter character should be chosen for concatenating arguments in the B-TREE-P subroutine calls.