How can I, Iterate over Hash table (fhash_tbl_t)

I have been using the @lkedward fhash module in my recent project. However, I’m unsure how to iterate over my hash table using this module. Could anyone advise me on how to do this? Here’s the code I’m working with.

use fhash, only: fhash_tbl_t, key => fhash_key
implicit none

type(fhash_tbl_t) :: tbl
integer :: i, val

! Insert some values into the hash table
call tbl%set(key('name 1'), value='value 1')
call tbl%set(key('name 2'), value='value 2')
call tbl%set(key('name 3'), value='value 3')
call tbl%set(key('name 4'), value='value 4')

I would like to achieve something similar to this.

! Iterate over the hash table
do i = 1, tbl%size()
    call tbl%fhash_iterate(i, key=key, value=val)
    ! Do something with key and value
end do

What I want to do is to use this hash table to store HTTP request headers as key-value pairs in the form of strings.

Hi Rajkumar @rajkumardongre ,

Unfortunately, I didn’t get around to implementing an item iterator yet, see Implement item iterator · Issue #2 · LKedward/fhash (github.com).

@lewisfish has made a rough implementation here, however I haven’t had a chance to cleanup and merge his implementation.

Please feel free to pick up this issue and make a contribution to fhash if you have the time - I’d be happy to provide support on it.

3 Likes

Thank you, @lkedward. I will definitely try to find time to look into it.

For other users of fhash and future readers, I’ve now implemented and merged a basic item iterator for the hash table type.

Example:

  type(fhash_tbl_t) :: tbl
  type(fhash_iter_t) :: iter
  class(fhash_key_t), allocatable :: ikey
  class(*), allocatable :: idata

  call tbl%set(key('my_key_1'), value=10)
  !  ... set key-value data ...

  !> Iterate over all items in table
  iter = fhash_iter_t(tbl)
  do while(iter%next(ikey,idata))

    write(*,*) 'Key = "'//ikey%to_string()//'"'

    call print_polymorphic(idata)

  end do

! call iter%reset()  ! (Reset if iterator needed again)

See the full example here: Example: Iterating over hash table items – fhash API Reference (lkedward.github.io)

Note: Data values are currently returned as an unlimited polymorphic entity - I may in the future write some generic interfaces for the intrinsics types in the same way that the main hash table type already has for its get method.

4 Likes

Thanks @lkedward, this is great! One question, is there a preferred way to erase a table? I can iterate though a loop, but thought there may be an easier way.

1 Like

Giving it some more thought, I think I am going to put the fhash function into a module, so maybe I don’t need a reset function. But could be a nice add at some point.

Also, is the number of buckets the max number of items, or something else?

Much appreciated.

Thanks for the feedback Chris @Chuckyvt and welcome to the forum!

No, there isn’t a way to do this currently, but you’re right there should be an erase routine for this purpose - I will add it when I get a chance!

Good question: the number of buckets is not the maximum number of items. There isn’t a maximum number of items imposed by the fhash library, it uses ‘chaining’ with linked-lists to resolve collisions and grow dynamically if needed. For performance reasons, you want the number of items stored to only be a fraction (maybe 50%) of the number of buckets.

If you have a rough idea of how many items you will store, then you can set the number of buckets with:

call tbl%allocate(n)

Where n is some integer multiple of the number of expected items.

As the number of items stored approaches or exceeds the number of buckets, you will encounter more ‘collisions’, which each add an extra level of indirection to the lookup and making it slower. Hope that made sense!

2 Likes

Got it, thanks for the info.

Another suggestion that for the road map for fhash. I think you have most all the building blocks to replicate the ‘Set’ data type in Python. Perhaps a ‘set’ type, but would just have the data field. Behind the scenes its hashes the data, and the key and data are the same.

2 Likes