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
85 class(*), target :: value
86 logical, optional :: clone
87 type(sphash_value_t), pointer :: constructor
88
89 allocate(constructor)
90 constructor%clone = optional_default(clone, .false.)
91
92 if (constructor%clone) then
93 allocate(constructor%value, source=value)
94 else
95 constructor%value => value
96 end if
97
98 end function sphash_value_constructor
99
100
101 subroutine sphash_value_finalize(this)
102
103 type(sphash_value_t) :: this
104
105 if (associated(this%value)) then
106 if (this%clone) then
107 deallocate(this%value)
108 else
109 nullify(this%value)
110 end if
111 end if
112
113 end subroutine sphash_value_finalize
114
115
116 function sphash_value_get(this) result(value)
117 class(sphash_value_t), intent(in) :: this
118 class(*), pointer :: value
119
120 value => this%value
121
122 end function sphash_value_get
123
128 subroutine sphash_init(h)
129 type(sphash_t), intent(out) :: h
130
131 interface
132 subroutine sphash_map_init(map) bind(c)
133 use iso_c_binding
134 import
135 implicit none
136
137 type(c_ptr) :: map
138 end subroutine sphash_map_init
139 end interface
141 call sphash_map_init(h%map)
143 end subroutine sphash_init
144
146 logical function sphash_is_associated(this)
147 class(sphash_t), intent(in) :: this
148
149 sphash_is_associated = c_associated(this%map)
150
151 end function sphash_is_associated
154 subroutine sphash_end(h)
155 type(sphash_t), intent(inout) :: h
157 type(sphash_iterator_t) :: it
158 type(c_ptr) :: tmp_ptr
159 type(sphash_value_t), pointer :: tmp_value
160
161 interface
162 subroutine sphash_iterator_low_get(iterator, value_ptr) bind(c)
163 use iso_c_binding
164 import
165 implicit none
166
167 type(c_ptr), intent(in) :: iterator
168 type(c_ptr), intent(out) :: value_ptr
170 end subroutine sphash_iterator_low_get
171
172 subroutine sphash_map_end(map) bind(c)
173 use iso_c_binding
174 import
175 implicit none
177 type(c_ptr) :: map
178 end subroutine sphash_map_end
179 end interface
180
181 call it%start(h)
182
183 do while (it%has_next())
184 call sphash_iterator_low_get(it%iterator, tmp_ptr)
185 call c_f_pointer(tmp_ptr, tmp_value)
186 deallocate(tmp_value)
187 end do
188
189 call sphash_map_end(h%map)
190
191 end subroutine sphash_end
192
193
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))
220
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 type(sphash_value_t), pointer :: tmp_value
236 character(kind=c_char), dimension(c_str_len(key)) :: c_key
237
238 interface
239 subroutine sphash_map_lookup(map, key, ifound, val) bind(c)
240 use iso_c_binding
241 implicit none
242
243 type(c_ptr), value :: map
244 character(kind=c_char), intent(in) :: key(*)
245 integer(kind=c_int), intent(out) :: ifound
246 type(c_ptr), intent(out) :: val
247 end subroutine sphash_map_lookup
248 end interface
249
250 integer :: ifound
251 type(c_ptr) :: val
252
253 c_key = string_f_to_c(key)
254 !Passing string_f_to_c as an arg creates a temporary array (ifort)
255 call sphash_map_lookup(h%map, c_key, ifound, val)
256
257 found = (ifound == 1)
258
259 nullify(value)
260 if (found) then
261 call c_f_pointer(val, tmp_value)
262 value => tmp_value%get()
263 end if
264
265 end function sphash_lookup
266
267 ! ---------------------------------------------------------
268 subroutine sphash_iterator_start(this, h)
269 class(sphash_iterator_t), intent(inout) :: this
270 class(sphash_t), intent(in) :: h
271
272 interface
273 subroutine sphash_iterator_low_start(iterator, end, map) bind(c)
274 use iso_c_binding
275 import
276 implicit none
277
278 type(c_ptr) :: iterator
279 type(c_ptr) :: end
280 type(c_ptr), value :: map
281 end subroutine sphash_iterator_low_start
282 end interface
283
284 call sphash_iterator_low_start(this%iterator, this%end, h%map)
285
286 end subroutine sphash_iterator_start
287
288 ! ---------------------------------------------------------
289 logical function sphash_iterator_has_next(this)
290 class(sphash_iterator_t), intent(in) :: this
291
292 integer :: value
293
294 interface
295 subroutine sphash_iterator_low_has_next(iterator, end, value) bind(c)
296 use iso_c_binding
297 import
298 implicit none
299
300 type(c_ptr), value, intent(in) :: iterator
301 type(c_ptr), value, intent(in) :: end
302 integer(kind=c_int), intent(out) :: value
303
304 end subroutine sphash_iterator_low_has_next
305 end interface
306
307 call sphash_iterator_low_has_next(this%iterator, this%end, value)
308
309 sphash_iterator_has_next = (value /= 0)
310
311 end function sphash_iterator_has_next
312
313 ! ---------------------------------------------------------
314 function sphash_iterator_get_next(this) result(value)
315 class(sphash_iterator_t), intent(inout) :: this
316 class(*), pointer :: value
317
318 type(c_ptr) :: tmp_ptr
319 type(sphash_value_t), pointer :: tmp_value
320
321 interface
322 subroutine sphash_iterator_low_get(iterator, value_ptr) bind(c)
323 use iso_c_binding
324 import
325 implicit none
326
327 type(c_ptr), intent(in) :: iterator
328 type(c_ptr), intent(out) :: value_ptr
329
330 end subroutine sphash_iterator_low_get
331 end interface
332
333 call sphash_iterator_low_get(this%iterator, tmp_ptr)
334
335 call c_f_pointer(tmp_ptr, tmp_value)
336 value => tmp_value%get()
337
338 end function sphash_iterator_get_next
339
340
341end module sphash_oct_m
342
343!! Local Variables:
344!! mode: f90
345!! coding: utf-8
346!! 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:408
subroutine sphash_value_finalize(this)
Definition: sphash.F90:195
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:222
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:383
class(*) function, pointer sphash_value_get(this)
Definition: sphash.F90:210
subroutine, public sphash_end(h)
Free a hash table.
Definition: sphash.F90:248
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:362
logical function sphash_is_associated(this)
Check if the sphash attribute, map, is associated.
Definition: sphash.F90:240
character(kind=c_char, len=1) function, dimension(c_str_len(f_string)), public string_f_to_c(f_string)
Definition: string.F90:265