Octopus
sphash.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2021 M. Marques, A. Castro, A. Rubio, G. Bertsch,
2!! M. Lueders
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
24
25module sphash_oct_m
26 use global_oct_m
27 use string_oct_m
28
29 use iso_c_binding
30
31 implicit none
32
33 private
34 public :: &
35 sphash_t, &
37 sphash_end, &
41
42 ! ---------------------------------------------------------
43
45 private
46 class(*), pointer :: value
47 logical :: clone
48 contains
49 procedure :: get => sphash_value_get
51 end type sphash_value_t
52
53 interface sphash_value_t
54 procedure :: sphash_value_constructor
55 end interface sphash_value_t
56
57 ! ---------------------------------------------------------
58
59 type sphash_t
60 private
61 type(c_ptr) :: map = c_null_ptr
62 contains
63 procedure :: is_associated => sphash_is_associated
64 end type sphash_t
65
66 ! ---------------------------------------------------------
67
69 private
70
71 type(c_ptr) :: iterator = c_null_ptr
72 type(c_ptr) :: end = c_null_ptr
73
74 contains
75 procedure :: start => sphash_iterator_start
76 procedure :: has_next => sphash_iterator_has_next
77 procedure :: get_next => sphash_iterator_get_next
78 end type sphash_iterator_t
79
80contains
81
82
83 function sphash_value_constructor(value, clone) result(constructor)
84 class(*), target, intent(in) :: value
85 logical, optional, intent(in) :: clone
86 type(sphash_value_t), pointer :: constructor
87
88 allocate(constructor)
89 constructor%clone = optional_default(clone, .false.)
90
91 if (constructor%clone) then
92 allocate(constructor%value, source=value)
93 else
94 constructor%value => value
95 end if
96
97 end function sphash_value_constructor
98
99
100 subroutine sphash_value_finalize(this)
101
102 type(sphash_value_t) :: this
103
104 if (associated(this%value)) then
105 if (this%clone) then
106 deallocate(this%value)
107 else
108 nullify(this%value)
109 end if
110 end if
111
112 end subroutine sphash_value_finalize
113
114
115 function sphash_value_get(this) result(value)
116 class(sphash_value_t), intent(in) :: this
117 class(*), pointer :: value
119 value => this%value
120
121 end function sphash_value_get
122
127 subroutine sphash_init(h)
128 type(sphash_t), intent(out) :: h
129
130 interface
131 subroutine sphash_map_init(map) bind(c)
132 use iso_c_binding
133 import
134 implicit none
135
136 type(c_ptr) :: map
137 end subroutine sphash_map_init
138 end interface
140 call sphash_map_init(h%map)
141
142 end subroutine sphash_init
145 logical function sphash_is_associated(this)
146 class(sphash_t), intent(in) :: this
147
148 sphash_is_associated = c_associated(this%map)
149
150 end function sphash_is_associated
151
153 subroutine sphash_end(h)
154 type(sphash_t), intent(inout) :: h
155
157 type(c_ptr) :: tmp_ptr
158 type(sphash_value_t), pointer :: tmp_value
159
160 interface
161 subroutine sphash_iterator_low_get(iterator, value_ptr) bind(c)
162 use iso_c_binding
163 import
164 implicit none
166 type(c_ptr), intent(in) :: iterator
167 type(c_ptr), intent(out) :: value_ptr
169 end subroutine sphash_iterator_low_get
171 subroutine sphash_map_end(map) bind(c)
172 use iso_c_binding
173 import
174 implicit none
175
176 type(c_ptr) :: map
177 end subroutine sphash_map_end
178 end interface
179
180 call it%start(h)
181
182 do while (it%has_next())
183 call sphash_iterator_low_get(it%iterator, tmp_ptr)
184 call c_f_pointer(tmp_ptr, tmp_value)
185 deallocate(tmp_value)
186 end do
187
188 call sphash_map_end(h%map)
189 h%map = c_null_ptr
190
191 end subroutine sphash_end
192
194 ! ---------------------------------------------------------
197 subroutine sphash_insert(h, key, val, clone)
198 type(sphash_t), intent(inout) :: h
199 character(len=*), intent(in) :: key
200 class(*), target, intent(in) :: val
201 logical, optional, intent(in) :: clone
202
203 type(sphash_value_t), pointer :: value
204
205 interface
206 subroutine sphash_map_insert(map, key, val) bind(c)
207 use iso_c_binding
208 import
209 implicit none
210
211 type(c_ptr), value :: map
212 character(kind=c_char), intent(in) :: key(*)
213 type(c_ptr), value :: val
214 end subroutine sphash_map_insert
215 end interface
216
217 value => sphash_value_t(val, clone)
218
219 call sphash_map_insert(h%map, string_f_to_c(key), c_loc(value))
221 end subroutine sphash_insert
222
223
224 ! ---------------------------------------------------------
229 function sphash_lookup(h, key, found) result(value)
230 type(sphash_t), intent(in) :: h
231 character(len=*), intent(in) :: key
232 logical, optional, intent(out) :: found
233 class(*), pointer :: value
234
235 logical :: found_
236 type(sphash_value_t), pointer :: tmp_value
237 character(kind=c_char), dimension(c_str_len(key)) :: c_key
239 interface
240 subroutine sphash_map_lookup(map, key, ifound, val) bind(c)
241 use iso_c_binding
242 implicit none
243
244 type(c_ptr), value :: map
245 character(kind=c_char), intent(in) :: key(*)
246 integer(kind=c_int), intent(out) :: ifound
247 type(c_ptr), intent(out) :: val
248 end subroutine sphash_map_lookup
249 end interface
250
251 integer :: ifound
252 type(c_ptr) :: val
253
254 c_key = string_f_to_c(key)
255 !Passing string_f_to_c as an arg creates a temporary array (ifort)
256 call sphash_map_lookup(h%map, c_key, ifound, val)
257
258 found_ = (ifound == 1)
259 if (present(found)) found = found_
260
261 nullify(value)
262 if (found_) then
263 call c_f_pointer(val, tmp_value)
264 value => tmp_value%get()
265 end if
266
267 end function sphash_lookup
268
269 ! ---------------------------------------------------------
270 subroutine sphash_iterator_start(this, h)
271 class(sphash_iterator_t), intent(inout) :: this
272 class(sphash_t), intent(in) :: h
273
274 interface
275 subroutine sphash_iterator_low_start(iterator, end, map) bind(c)
276 use iso_c_binding
277 import
278 implicit none
279
280 type(c_ptr) :: iterator
281 type(c_ptr) :: end
282 type(c_ptr), value :: map
283 end subroutine sphash_iterator_low_start
284 end interface
285
286 call sphash_iterator_low_start(this%iterator, this%end, h%map)
287
288 end subroutine sphash_iterator_start
289
290 ! ---------------------------------------------------------
291 logical function sphash_iterator_has_next(this)
292 class(sphash_iterator_t), intent(in) :: this
293
294 integer :: value
295
296 interface
297 subroutine sphash_iterator_low_has_next(iterator, end, value) bind(c)
298 use iso_c_binding
299 import
300 implicit none
301
302 type(c_ptr), value, intent(in) :: iterator
303 type(c_ptr), value, intent(in) :: end
304 integer(kind=c_int), intent(out) :: value
305
306 end subroutine sphash_iterator_low_has_next
307 end interface
308
309 call sphash_iterator_low_has_next(this%iterator, this%end, value)
310
311 sphash_iterator_has_next = (value /= 0)
312
313 end function sphash_iterator_has_next
314
315 ! ---------------------------------------------------------
316 function sphash_iterator_get_next(this) result(value)
317 class(sphash_iterator_t), intent(inout) :: this
318 class(*), pointer :: value
319
320 type(c_ptr) :: tmp_ptr
321 type(sphash_value_t), pointer :: tmp_value
323 interface
324 subroutine sphash_iterator_low_get(iterator, value_ptr) bind(c)
325 use iso_c_binding
326 import
327 implicit none
328
329 type(c_ptr), intent(in) :: iterator
330 type(c_ptr), intent(out) :: value_ptr
331
332 end subroutine sphash_iterator_low_get
333 end interface
334
335 call sphash_iterator_low_get(this%iterator, tmp_ptr)
336
337 call c_f_pointer(tmp_ptr, tmp_value)
338 value => tmp_value%get()
339
340 end function sphash_iterator_get_next
341
342
343end module sphash_oct_m
344
345!! Local Variables:
346!! mode: f90
347!! coding: utf-8
348!! End:
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
Definition: sphash.F90:118
class(*) function, pointer sphash_iterator_get_next(this)
Definition: sphash.F90:410
subroutine sphash_value_finalize(this)
Definition: sphash.F90:194
subroutine, public sphash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
Definition: sphash.F90:221
subroutine, public sphash_insert(h, key, val, clone)
Insert a (key, val) pair into the hash table h. If clone=.true., the object will be copied.
Definition: sphash.F90:291
logical function sphash_iterator_has_next(this)
Definition: sphash.F90:385
class(*) function, pointer sphash_value_get(this)
Definition: sphash.F90:209
subroutine, public sphash_end(h)
Free a hash table.
Definition: sphash.F90:247
type(sphash_value_t) function, pointer sphash_value_constructor(value, clone)
Definition: sphash.F90:177
class(*) function, pointer, public sphash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
Definition: sphash.F90:323
subroutine sphash_iterator_start(this, h)
Definition: sphash.F90:364
logical function sphash_is_associated(this)
Check if the sphash attribute, map, is associated.
Definition: sphash.F90:239
character(kind=c_char, len=1) function, dimension(c_str_len(f_string)), public string_f_to_c(f_string)
convert a Fortran string to a C string
Definition: string.F90:252