Commented source code for BTPFIND

    C.BTPFIND
001 SUBROUTINE BTPFIND(ROOT,BFILE,DFILE,ID,ITEM,NODE.ID,NODE.POS)
002 * Find node containing key, with nodes in following format:
003 *   AMC 0:  Arbitrary node number.
004 *   AMC 1:  Count of keys in node.
005 *   AMC 2:  Keys, stored as a subvalue list.
006 *   AMC 3:  (number of keys)+1 pointers to next nodes.
007 *   AMC 4:  Pointer to parent if any.
008 CALL BTPKEY(ROOT,ID,ITEM,FINDKEY) ;* Get sort string for comparing to rest of tree
009 READ NODE.ID FROM BFILE, ROOT ELSE STOP "No root"
010 100 READ NODE FROM BFILE, NODE.ID ELSE STOP "Can't find node"
011 LEFT = 0 ; RIGHT = NODE<1>+1 ;* Boundaries for binary search of keys in node
012 IF RIGHT = 1 THEN NODE.POS = 1 ELSE ;* Not an empty root
013   LOOP
014     NODE.POS = INT((LEFT+RIGHT)/2) ;* Find position midway between boundaries
015     COMPARE.ID = NODE<2,NODE.POS> ;* Get that key
016     IF COMPARE.ID = ID THEN RETURN ;* Key is already in node
017     READ COMPARE.ITEM FROM DFILE, COMPARE.ID ELSE STOP "Can't read"
018     CALL BTPKEY(ROOT,COMPARE.ID,COMPARE.ITEM,KEY) ;* Convert COMPARE.ITEM to KEY for comparison
019     IS.GREATER = (FINDKEY > KEY) ;* Is our key greater than node key?
020     IF IS.GREATER THEN LEFT = NODE.POS ELSE RIGHT = NODE.POS ;* Adjust search boundaries
021   UNTIL (RIGHT-LEFT) <= 1 DO REPEAT
022   IF IS.GREATER THEN NODE.POS = RIGHT ;* Else NODE.POS already OK
023   END
024 NEXT.NODE.ID = NODE<3, NODE.POS> ;* Get id of next node
025 IF NEXT.NODE.ID # "" THEN ;* There's another node, keep looking for leaf
026   NODE.ID = NEXT.NODE.ID
027   GO TO 100
028   END
029 IF NODE.POS <= NODE<1> THEN ID = NODE<2,NODE.POS> ; RETURN
030 * At end of node, get next id like Branches #5 describes
031 NODE.POS = NODE<1> ; LAST.NODE.ID = NODE.ID
032 CALL BTPSEQ(BFILE,NODE.ID,NODE.POS,"NEXT",ID)
033 IF ID = "" THEN ;* Past end of tree, use last id
034   NODE.POS = NODE<1>
035   ID = NODE<2,NODE.POS>
036   NODE.ID = LAST.NODE.ID
037   END
038 RETURN
039 END