-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abstract base class for map types #479
Comments
Is map the same as dictionary (e.g. Python's In Python I work with this a lot. In Fortran, not really. But this is one of the features that I think, even if not presently used a lot, would open up many possibilities for development of high level libraries. For example, databases (SQL-style or otherwise), various file formats, parsing HTML, SVG, and other kinds of XML, HTTP clients and servers. Fortran-native approach is the way to go. An alternative, perhaps for its own package rather than stdlib, would be Fortran bindings for Redis, which provides high performance in-memory dicts and lists. |
I have worked on a Fortran interface to Redis, but I ran into odd problems
that I simply did not understand. I would have to look up my notes, but if
there is interest I can revive it ;).
Op wo 25 aug. 2021 om 17:00 schreef Milan Curcic ***@***.***>:
… Is map the same as dictionary (e.g. Python's dict) or do they differ in
some ways?
In Python I work with this a lot. In Fortran, not really. But this is one
of the features that I think, even if not presently used a lot, would open
up many possibilities for development of high level libraries. For example,
databases (SQL-style or otherwise), various file formats, parsing HTML,
SVG, and other kinds of XML, HTTP clients and servers.
Fortran-native approach is the way to go.
An alternative, perhaps for its own package rather than stdlib, would be
Fortran bindings for Redis <https://redis.io/>, which provides high
performance in-memory dicts and lists.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#479 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN6YR7BPOKEAPHPCNWKYEDT6UAQFANCNFSM5BIOAAUQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email>
.
|
I was thinking C++ ordered map, but Python dictionary is the same thing. Having an abstract base class would allow to implement the map type with any backend, stdlib would only provide the base class and pure Fortran implementations. Other (fpm) projects could extend the base class and provide their own optimized implementation. The advantage of a single well-designed abstract base class would be that projects like TOML Fortran don't have to implement their own, but you could simply load a TOML document into a stdlib map type and use it with any other library which supports stdlib's maps. Designed correctly a library could also load data directly into an optimized map implementation. |
For the record, are you aware of fhash? |
FWIW I have just released a proposed hash map API on the website with my proposed hash function API. The API defines three modules: The The module The module The API's for the two data types are very similar. The The two APIs also have some inquiry functions on the structure and history of the hash maps that could be eliminated. In particular I think the |
FWIW I have just changed the implementation of |
There's also my own implementation of the same name: LKedward/fhash. |
Would it make sense to introduce an abstract base class which both implementation inherit from? Except for the delete feature which is absent in the open addressing implementation the APIs seem pretty much similar. |
@FObermaier the flash you refer to is based on the gcc hash table and, as a result, is probably covered by the GNU LGPL license, which I believe is not compatible with the MIT license used by the Fortran Standard Library. |
@awvwgk I have tried to keep the APIs for the hash tables very similar. The init procedures differ, but that is because I provide additional features through optional arguments that most users would not use. I should probably reduce it to four arguments: |
No, it is not based on it, it is an implemention of the GCC hashmap structure in Fortran. Not a port of the GCC code. I think that is fine and it is MIT licensed, too. |
Any news on this? |
The documentation is immense and hard to navigate. Is there a rosetta stone of how to do the python equivalent of: dict = {}
dict.__contains__("key")
dict["key"] = 2
dict.pop("key") |
@LecrisUT I agree with you that the specs are quite difficult to follow and is not written for users. Unfortunately, I never found the time to write a tutorial. program main
use stdlib_kinds, only: int8
use stdlib_hashmap_wrappers, only: fnv_1_hasher, key_type, other_type, set, get
use stdlib_hashmaps, only: chaining_hashmap_type, default_bits
implicit none
integer, parameter :: nentries = 50
type dummy_type
integer :: i
real :: myval(4)
end type dummy_type
integer :: i
logical :: conflict, exists
type(dummy_type) :: dummy
type(key_type) :: key
type(other_type) :: other
type(chaining_hashmap_type) :: map
class(*), allocatable :: data
call map%init(fnv_1_hasher)
!Storing data
do i = 1, nentries
dummy%i = i
call random_number(dummy%myval)
call set(key, [transfer("dummy", 1_int8, len("dummy")), transfer(i, 1_int8)])
call set(other, dummy)
call map%map_entry(key, other, conflict)
if(conflict) error stop "Unable to map entry because of a key conflict"
enddo
write(*, '(a)')'Querying table info...'
write(*, '(a,t40,i0)')'Number of buckets allocated: ',map%num_slots()
write(*, '(a,t40,i0)')'Number of key-value pairs stored: ',map%entries()
write(*, '(a,t40,i0)')'The worst case bucket depth is ',map%total_depth()
!Retrieving data
do i = 1, nentries
call set(key, [transfer("dummy", 1_int8, len("dummy")), transfer(i, 1_int8)])
call map%get_other_data(key, other, exists)
if(.not.exists)write(*,'(a)')'Warning: missing key other'
call get(other, data)
select type (data)
type is (dummy_type)
print *, 'Other data % i = ', data%i
print *, 'Other data % myval = ', data%myval
class default
print *, 'Invalid data type in other'
end select
enddo
end program main |
So to get this straight:
That is quite a lot of boilerplate, but at least it manages to get me started. Will there be a simpler interface some day? |
I think you got the idea.
Note that in my example, my key is composed of both
Actually the call set(key, [transfer("dummy", 1_int8, len("dummy")), transfer(i, 1_int8)])
call set(other, dummy)
call map%map_entry(key, other, conflict) by (with key aliasing key_type and other aliasing other_type): call map%map_entry(key([transfer("dummy", 1_int8, len("dummy")), transfer(i, 1_int8)]), other(dummy), conflict)
I guess it is. In my opinion, it gives a lot of (too much) flexibility to the users. I don't think there are plans to simplify the interfaces. However, wrappers could be added, and we are open to feedbacks from users to improve it. |
Well, one thing I couldn't find is how to store and retrieve pointers instead of values |
Do you mean something like that: input = 'aaaarrrr'
output => input
call map%map_entry(key_type([transfer("pointer", 1_int8, len("pointer"))]), other_type(output), conflict)
call map%get_other_data(key_type([transfer("pointer", 1_int8, len("pointer"))]), other, exists)
call get(other, data)
select type (data)
type is (character(*))
print *, 'character = ', data
class default
print *, 'Invalid data type in other'
end select |
I think it is when using non-intrisic data types so that it can only use Fortran language really needs templating to cut down all of the boilerplate. |
I think overloading it is indeed the right way.
I agree with you. |
Took me a bit of digging, but I found an issue with the previous example: ! This one only sets transfers "d"
call set(key, [transfer("dummy", 1_int8)])
! Should be
call set(key, [transfer("dummy", 1_int8, len("dummy")]) |
@LecrisUT Good catch! Thank you. I'll edit my posts. Sorry for the troubles! |
Description
This issue should track a potential addition of a map class to stdlib. I think it would be preferable to first define an abstract base class which covers most of our needs. Here are some points I found important when working on TOML Fortran:
Examples
Abstract base class used in TOML Fortran to define maps
The text was updated successfully, but these errors were encountered: