29 #include "./base/base_uses.f90"
36 PUBLIC :: fb_hash_table_obj
47 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_fb_hash_table_types'
50 INTEGER(KIND=int_8),
PARAMETER,
PRIVATE :: EMPTY_KEY = -1_int_8
53 INTEGER,
PARAMETER,
PRIVATE :: ENLARGE_RATIO = 1
54 INTEGER,
PARAMETER,
PRIVATE :: REDUCE_RATIO = 3
55 INTEGER,
PARAMETER,
PRIVATE :: EXPAND_FACTOR = 2
56 INTEGER,
PARAMETER,
PRIVATE :: SHRINK_FACTOR = 2
64 TYPE fb_hash_table_element
65 INTEGER(KIND=int_8) :: key
67 END TYPE fb_hash_table_element
79 TYPE fb_hash_table_data
80 TYPE(fb_hash_table_element),
DIMENSION(:),
POINTER :: table => null()
84 END TYPE fb_hash_table_data
92 TYPE fb_hash_table_obj
93 TYPE(fb_hash_table_data),
POINTER,
PRIVATE :: obj => null()
94 END TYPE fb_hash_table_obj
106 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
107 INTEGER(KIND=int_8),
INTENT(IN) :: key
108 INTEGER,
INTENT(IN) :: val
116 IF (hash_table%obj%nelements*enlarge_ratio .GE. &
117 hash_table%obj%nmax)
THEN
118 CALL fb_hash_table_rehash(hash_table=hash_table, &
119 nmax=hash_table%obj%nmax*expand_factor)
122 islot = fb_hash_table_linear_probe(hash_table, key)
126 IF (hash_table%obj%table(islot)%key == empty_key)
THEN
127 hash_table%obj%nelements = hash_table%obj%nelements + 1
128 hash_table%obj%table(islot)%key = key
130 hash_table%obj%table(islot)%val = val
142 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
143 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
150 ALLOCATE (hash_table%obj)
151 NULLIFY (hash_table%obj%table)
152 hash_table%obj%nmax = 0
153 hash_table%obj%nelements = 0
154 hash_table%obj%prime = 2
156 IF (
PRESENT(nmax)) my_nmax = nmax
157 CALL fb_hash_table_init(hash_table=hash_table, &
171 TYPE(fb_hash_table_obj),
INTENT(IN) :: hash_table
172 INTEGER(KIND=int_8),
INTENT(IN) :: key
173 INTEGER,
INTENT(OUT) :: val
174 LOGICAL,
INTENT(OUT) :: found
183 islot = fb_hash_table_linear_probe(hash_table, key)
185 IF (hash_table%obj%table(islot)%key == key)
THEN
186 val = hash_table%obj%table(islot)%val
199 TYPE(fb_hash_table_obj),
INTENT(IN) :: hash_table
202 res =
ASSOCIATED(hash_table%obj)
213 SUBROUTINE fb_hash_table_init(hash_table, nmax)
214 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
215 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
217 INTEGER :: ii, my_nmax, power
222 my_nmax = hash_table%obj%nmax
223 IF (
PRESENT(nmax)) my_nmax = nmax
227 DO WHILE (2**power .LT. my_nmax)
231 IF (
ASSOCIATED(hash_table%obj%table))
THEN
232 IF (
SIZE(hash_table%obj%table) .NE. my_nmax)
THEN
233 DEALLOCATE (hash_table%obj%table)
234 ALLOCATE (hash_table%obj%table(my_nmax))
237 ALLOCATE (hash_table%obj%table(my_nmax))
239 hash_table%obj%nmax = my_nmax
242 DO ii = 1, hash_table%obj%nmax
243 hash_table%obj%table(ii)%key = empty_key
244 hash_table%obj%table(ii)%val = 0
246 hash_table%obj%nelements = 0
247 END SUBROUTINE fb_hash_table_init
255 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
257 NULLIFY (hash_table%obj)
267 RECURSIVE SUBROUTINE fb_hash_table_rehash(hash_table, nmax)
268 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
269 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
271 INTEGER :: ii, my_nmax
272 TYPE(fb_hash_table_element),
ALLOCATABLE, &
273 DIMENSION(:) :: tmp_table
279 IF (
PRESENT(nmax))
THEN
280 my_nmax = max(nmax, hash_table%obj%nelements)
282 my_nmax = hash_table%obj%nmax
284 ALLOCATE (tmp_table(hash_table%obj%nmax))
285 tmp_table(:) = hash_table%obj%table(:)
289 DO ii = 1,
SIZE(tmp_table)
290 IF (tmp_table(ii)%key .NE. empty_key)
THEN
292 key=tmp_table(ii)%key, &
293 val=tmp_table(ii)%val)
296 DEALLOCATE (tmp_table)
297 END SUBROUTINE fb_hash_table_rehash
305 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
307 IF (
ASSOCIATED(hash_table%obj))
THEN
308 IF (
ASSOCIATED(hash_table%obj%table))
THEN
309 DEALLOCATE (hash_table%obj%table)
311 DEALLOCATE (hash_table%obj)
313 NULLIFY (hash_table%obj)
323 SUBROUTINE fb_hash_table_remove(hash_table, key)
324 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
325 INTEGER(KIND=int_8),
INTENT(IN) :: key
332 islot = fb_hash_table_linear_probe(hash_table, key)
335 IF (hash_table%obj%table(islot)%key == key)
THEN
336 hash_table%obj%table(islot)%key = empty_key
337 hash_table%obj%nelements = hash_table%obj%nelements - 1
340 IF (hash_table%obj%nelements*reduce_ratio .LT. &
341 hash_table%obj%nmax)
THEN
342 CALL fb_hash_table_rehash(hash_table=hash_table, &
343 nmax=hash_table%obj%nmax/shrink_factor)
345 CALL fb_hash_table_rehash(hash_table=hash_table)
349 END SUBROUTINE fb_hash_table_remove
359 SUBROUTINE fb_hash_table_status(hash_table, nelements, nmax, prime)
360 TYPE(fb_hash_table_obj),
INTENT(INOUT) :: hash_table
361 INTEGER,
INTENT(OUT),
OPTIONAL :: nelements, nmax, prime
367 IF (
PRESENT(nelements)) nelements = hash_table%obj%nelements
368 IF (
PRESENT(nmax)) nmax = hash_table%obj%nmax
369 IF (
PRESENT(prime)) prime = hash_table%obj%prime
370 END SUBROUTINE fb_hash_table_status
380 PURE FUNCTION fb_hash_table_linear_probe(hash_table, key) &
382 TYPE(fb_hash_table_obj),
INTENT(IN) :: hash_table
383 INTEGER(KIND=int_8),
INTENT(IN) :: key
390 guess = fb_hash_table_hash_function(hash_table, key)
394 DO islot = guess, hash_table%obj%nmax
395 IF ((hash_table%obj%table(islot)%key == key) .OR. &
396 (hash_table%obj%table(islot)%key == empty_key))
RETURN
399 DO islot = 1, guess - 1
400 IF ((hash_table%obj%table(islot)%key == key) .OR. &
401 (hash_table%obj%table(islot)%key == empty_key))
RETURN
405 END FUNCTION fb_hash_table_linear_probe
415 PURE FUNCTION fb_hash_table_hash_function(hash_table, key)
RESULT(hash)
416 TYPE(fb_hash_table_obj),
INTENT(IN) :: hash_table
417 INTEGER(KIND=int_8),
INTENT(IN) :: key
420 INTEGER(KIND=int_8) :: hash_8, nmax_8, prime_8
422 nmax_8 = int(hash_table%obj%nmax,
int_8)
423 prime_8 = int(hash_table%obj%prime,
int_8)
425 hash_8 = iand(key*prime_8, nmax_8 - 1) + 1_int_8
427 END FUNCTION fb_hash_table_hash_function
static unsigned int hash(const dbm_task_t task)
Private hash function based on Szudzik's elegant pairing. Using unsigned int to return a positive num...
Defines the basic variable types.
integer, parameter, public int_8
A simple hash table of integer keys, using hash function: H(k) = (k*p) mod n + 1 where: k = key p = a...
pure logical function, public fb_hash_table_has_data(hash_table)
check if the object has data associated to it
recursive subroutine, public fb_hash_table_add(hash_table, key, val)
Add element to a hash table, auto resize if necessary.
subroutine, public fb_hash_table_release(hash_table)
releases given object
subroutine, public fb_hash_table_get(hash_table, key, val, found)
Retrieve value from a key from a hash table.
subroutine, public fb_hash_table_create(hash_table, nmax)
Creates and initialises an empty fb_hash_table object.
pure subroutine, public fb_hash_table_nullify(hash_table)
Nullifies a fb_hash_table object.
Functions which are common to different hash tables Derived from qs_fb_hash_table_types and qs_fb_has...
pure integer function, public hash_table_matching_prime(ii)
Find a prime number equal or larger than ii.