btree_add_into_i8_cp2d Subroutine

private recursive subroutine btree_add_into_i8_cp2d(tree, node, key, value, before, subtree)

Arguments

TypeIntentOptionalAttributesName
type(btree_i8_cp2d), intent(inout) :: tree
type(btree_node_i8_cp2d), POINTER:: node
integer(kind=keyt), intent(in) :: key
type(btree_data_cp2d), intent(in) :: value
integer, intent(in), optional :: before
type(btree_node_i8_cp2d), optional POINTER:: subtree

Contents


Source Code

      RECURSIVE SUBROUTINE btree_add_into_i8_cp2d (tree, node, key, value, before, subtree)
         TYPE(btree_i8_cp2d), INTENT(INOUT) :: tree
         TYPE(btree_node_i8_cp2d), POINTER :: node
         INTEGER(KIND=keyt), INTENT(IN) :: key
         TYPE(btree_data_cp2d), INTENT(IN) :: value
         INTEGER, INTENT(IN), OPTIONAL :: before
         TYPE(btree_node_i8_cp2d), POINTER, OPTIONAL :: subtree
         !
         TYPE(btree_node_i8_cp2d), POINTER :: new_node
         INTEGER(KIND=keyt) :: upgrade_key
         INTEGER :: ge_pos, split_pos
         TYPE(btree_data_cp2d) :: upgrade_value
         LOGICAL :: leaf
         !
         ! Root is special
         IF (.NOT. ASSOCIATED(node)) THEN
            CALL btree_new_root_i8_cp2d (tree, key, value)
            IF (PRESENT(subtree)) THEN
               tree%b%root%subtrees(2)%node => subtree
               subtree%parent => tree%b%root
            END IF
            RETURN
         END IF
         ! Where the insertion takes place.
         IF (PRESENT(before)) THEN
            ge_pos = before
         ELSE
            CALL btree_node_find_gt_pos_i8_cp2d (node%keys, key, ge_pos, node%filled)
         END IF
         ! Addition is easy if the node has enough space.
         leaf = .NOT. ASSOCIATED(node%subtrees(1)%node)
         IF (node%filled .LT. tree%b%max_fill) THEN
            IF (PRESENT(subtree)) THEN
               CALL btree_simple_insertion_i8_cp2d (node, key, value, ge_pos, subtree)
            ELSE
               CALL btree_simple_insertion_i8_cp2d (node, key, value, ge_pos)
            END IF
            RETURN
         ELSE
            split_pos = ISHFT(tree%b%max_fill + 1, -1)
            ! I assert that split_pos <= SIZE(node%keys)
            CALL btree_new_node_i8_cp2d (tree, new_node)
            ! The key to be added falls in the left node
            node%filled = split_pos - 1
            IF (ge_pos .LE. split_pos) THEN
               IF (ge_pos .EQ. split_pos) THEN
                  upgrade_key = key
                  upgrade_value = value
               ELSE
                  upgrade_key = node%keys(split_pos - 1)
                  upgrade_value = node%values(split_pos - 1)
               END IF
               IF (PRESENT(subtree)) THEN
                  CALL btree_left_insertion_i8_cp2d (tree, node, new_node, key, value, &
                                                          ge_pos, split_pos, subtree)
                  !CALL btree_adopt_subtrees_i8_cp2d (new_node)
               ELSE
                  CALL btree_left_insertion_i8_cp2d (tree, node, new_node, key, value, &
                                                          ge_pos, split_pos)
               END IF
               !
            ELSE
               upgrade_key = node%keys(split_pos)
               upgrade_value = node%values(split_pos)
               IF (PRESENT(subtree)) THEN
                  CALL btree_right_insertion_i8_cp2d (tree, node, new_node, key, value, &
                                                           ge_pos, split_pos, subtree)
                  !CALL btree_adopt_subtrees_i8_cp2d (new_node)
               ELSE
                  CALL btree_right_insertion_i8_cp2d (tree, node, new_node, key, value, &
                                                           ge_pos, split_pos)
               END IF
               !
            END IF
            !
            new_node%parent => node%parent
            !
            IF (.NOT. leaf) THEN
               CALL btree_adopt_subtrees_i8_cp2d (new_node)
            END IF
            !
            CALL btree_add_into_i8_cp2d (tree, node%parent, upgrade_key, upgrade_value, &
                                              subtree=new_node)
            !
         END IF
      END SUBROUTINE btree_add_into_i8_cp2d