SUBROUTINE btree_find_full_i8_sp2d (tree, key, node, position, ge_position, short)
TYPE(btree_i8_sp2d), INTENT(IN) :: tree
INTEGER(KIND=keyt), INTENT(IN) :: key
TYPE(btree_node_i8_sp2d), POINTER :: node
INTEGER, INTENT(OUT) :: position
INTEGER, INTENT(OUT), OPTIONAL :: ge_position
LOGICAL, INTENT(IN), OPTIONAL :: short
INTEGER :: gti ! Used mark searches
LOGICAL :: stop_short
!
stop_short = .FALSE.
IF (PRESENT(short)) stop_short = short
NULLIFY (node)
position = 0
IF (PRESENT(ge_position)) ge_position = 0
!IF (tree%b%n .EQ. 0) RETURN
IF (.NOT. ASSOCIATED(tree%b%root)) RETURN
gti = 1
! Try to find the key in the given node. If it's found, then
! return the node.
node => tree%b%root
descent: DO WHILE (.TRUE.)
! Try to find the first element equal to or greater than the
! one we're searching for.
CALL btree_node_find_ge_pos_i8_sp2d (node%keys, key, position, node%filled)
! One of three things is now true about position: it's now
! greater than the number of keys (if all keys are smaller), or
! it points to the key that is equal to or greater than the one
! we are searching for. If it is found and we are just
! searching for one equal element (i.e., user search), we can
! return.
IF (stop_short .AND. position .LE. node%filled) THEN
IF (node%keys(position) .EQ. key) THEN
IF (PRESENT(ge_position)) ge_position = position
RETURN
END IF
END IF
! If the key is not found, then either return the GE position
! if we're in a leaf (case 2 here), otherwise descend into the
! subtrees.
!CALL btree_node_find_gt_pos_i8_sp2d (node%keys, key, gti, node%filled, position)
CALL btree_node_find_gte_pos_i8_sp2d (node%keys, key, gti, node%filled, position)
IF (ASSOCIATED(node%subtrees(1)%node)) THEN
node => node%subtrees(gti)%node
ELSE
IF (PRESENT(ge_position)) ge_position = gti
position = 0
RETURN
END IF
END DO descent
END SUBROUTINE btree_find_full_i8_sp2d