reserve_entries Subroutine

private subroutine reserve_entries(this, needed)

Ensure the insertion-order arrays hold at least needed entries. Explicit allocate/copy/move_alloc rather than reallocation-on-assignment, which is shaky on some supported compilers.

Arguments

Type IntentOptional Attributes Name
class(hash_map_t), intent(inout) :: this
integer(kind=default_int), intent(in) :: needed

Called by

proc~~reserve_entries~~CalledByGraph proc~reserve_entries reserve_entries proc~hash_map_insert hash_map_t%hash_map_insert proc~hash_map_insert->proc~reserve_entries

Variables

Type Visibility Attributes Name Initial
integer(kind=default_int), private :: i
integer(kind=default_int), private :: new_cap
integer(kind=default_int), private, allocatable :: new_size(:)
integer(kind=default_int), private, allocatable :: new_start(:)
integer(kind=int64), private, allocatable :: new_value(:)

Source Code

   subroutine reserve_entries(this, needed)
      !! Ensure the insertion-order arrays hold at least `needed` entries.
      !! Explicit allocate/copy/`move_alloc` rather than
      !! reallocation-on-assignment, which is shaky on some supported
      !! compilers.
      class(hash_map_t), intent(inout) :: this
      integer(default_int), intent(in) :: needed

      integer(default_int), allocatable :: new_start(:), new_size(:)
      integer(int64), allocatable :: new_value(:)
      integer(default_int) :: new_cap, i

      if (needed <= this%entry_cap) return

      new_cap = max(this%entry_cap, MIN_ENTRIES)
      do while (new_cap < needed)
         new_cap = new_cap*2
      end do

      allocate (new_start(new_cap))
      allocate (new_size(new_cap))
      allocate (new_value(new_cap))
      do i = 1, this%n_entries
         new_start(i) = this%key_start(i)
         new_size(i) = this%key_size(i)
         new_value(i) = this%entry_value(i)
      end do

      deallocate (this%key_start)
      deallocate (this%key_size)
      deallocate (this%entry_value)
      call move_alloc(new_start, this%key_start)
      call move_alloc(new_size, this%key_size)
      call move_alloc(new_value, this%entry_value)
      this%entry_cap = new_cap
   end subroutine reserve_entries