Create a hash table from the children of an existing JSON object. The keys are the object member names and the values are pointers to the associated JSON values.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(json_hash_table), | intent(out) | :: | me | |||
| type(json_core), | intent(in) | :: | json |
the JSON core factory to use for this hash table. a copy of this will be made and stored in the table. |
||
| type(json_value), | pointer | :: | p |
the JSON value whose children will be used to populate the hash table. This must be a JSON object. |
||
| logical(kind=LK), | intent(out) | :: | status_ok |
true if no problems. |
||
| integer(kind=IK), | intent(in), | optional | :: | initial_capacity |
initial capacity of the hash table (number of buckets). If not provided, it will be set based on the number of members divided by the load factor to minimize the number of resizes needed as members are inserted |
subroutine hash_table_create_from_value(me, json, p, status_ok, initial_capacity) class(json_hash_table), intent(out) :: me type(json_core), intent(in) :: json !! the JSON core factory to use for this hash table. !! a copy of this will be made and stored in the table. type(json_value), pointer :: p !! the JSON value whose children will be used to populate !! the hash table. This must be a JSON object. logical(LK), intent(out) :: status_ok !! true if no problems. integer(IK), intent(in), optional :: initial_capacity !! initial capacity of the hash table (number of buckets). !! If not provided, it will be set based on the number of members !! divided by the load factor to minimize !! the number of resizes needed as members are inserted integer(IK) :: i !! counter integer(IK) :: n_members !! number of members in the JSON object integer (IK) :: var_type !! type of the JSON value character(kind=CK,len=:), allocatable :: key !! member names type(json_value), pointer :: current !! pointer to current member value type(json_value), pointer :: next !! pointer to next member value if (.not. associated(p)) then status_ok = .false. return end if status_ok = .true. ! will be set to false if any problems are encountered me%json = json ! make a copy call me%json%info(p, n_children=n_members, var_type=var_type) if (me%json%failed()) then call set_error() return end if if (n_members > 0_IK .and. var_type == json_object) then if (present(initial_capacity)) then me%capacity = initial_capacity else ! size it initially to the number of members divided by the load factor to minimize ! the number of resizes needed as members are inserted. me%capacity = ceiling(real(n_members, RK) / me%load_factor) end if ! enforce a minimum capacity to avoid too many collisions when there are few members me%capacity = max(me%capacity, 16_IK) ! get the key settings from the JSON object so that the hash ! table will be consistent with how keys are compared in the JSON library. ! store these in the hash table for easy access. call me%json%get_name_settings(case_sensitive_keys = me%case_sensitive_keys, & trailing_spaces_significant = me%trailing_spaces_significant) ! allocate the buckets: allocate(me%buckets(0:me%capacity-1)) ! iterate over each child member and insert into the hash table call me%json%get_child(p, 1_IK, current, found=status_ok) ! the first one if (.not. status_ok) then call set_error() ! should never happen since we know the size return end if do i = 1, n_members call me%json%info(current, name=key) if (me%json%failed()) then call set_error() return end if call me%insert(key, current) call me%json%get_next(current, next) ! get the next one in the list of children if (me%json%failed()) then call set_error() return end if current => next end do else ! can't create a hash table. status_ok = .false. end if contains subroutine set_error() !! clear any JSON exceptions and set error flag to false. call me%json%clear_exceptions() status_ok = .false. end subroutine set_error end subroutine hash_table_create_from_value