32 #include "./base/base_uses.f90"
39 PUBLIC :: nl_hash_table_obj
49 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_nl_hash_table_types'
52 INTEGER(KIND=int_8),
PARAMETER,
PRIVATE :: EMPTY_KEY = -1_int_8
55 INTEGER,
PARAMETER,
PRIVATE :: ENLARGE_RATIO = 1
56 INTEGER,
PARAMETER,
PRIVATE :: REDUCE_RATIO = 3
57 INTEGER,
PARAMETER,
PRIVATE :: EXPAND_FACTOR = 2
58 INTEGER,
PARAMETER,
PRIVATE :: SHRINK_FACTOR = 2
65 TYPE nl_hash_table_element
66 INTEGER(KIND=int_8) :: key
67 TYPE(neighbor_list_task_type),
POINTER :: val
68 END TYPE nl_hash_table_element
79 TYPE nl_hash_table_data
80 TYPE(nl_hash_table_element),
DIMENSION(:),
POINTER :: table => null()
84 END TYPE nl_hash_table_data
91 TYPE nl_hash_table_obj
92 TYPE(nl_hash_table_data),
POINTER,
PRIVATE :: obj => null()
93 END TYPE nl_hash_table_obj
104 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
105 INTEGER(KIND=int_8),
INTENT(IN) :: key
106 TYPE(neighbor_list_task_type),
INTENT(IN),
POINTER :: val
111 check_ok = nl_hash_table_has_data(hash_table)
115 IF (hash_table%obj%nelements*enlarge_ratio .GE. hash_table%obj%nmax)
THEN
116 CALL nl_hash_table_rehash(hash_table=hash_table, nmax=hash_table%obj%nmax*expand_factor)
120 islot = nl_hash_table_linear_probe(hash_table, key)
124 IF (hash_table%obj%table(islot)%key == empty_key)
THEN
125 hash_table%obj%nelements = hash_table%obj%nelements + 1
126 hash_table%obj%table(islot)%key = key
130 IF (
ASSOCIATED(hash_table%obj%table(islot)%val))
THEN
131 val%next => hash_table%obj%table(islot)%val
135 hash_table%obj%table(islot)%val => val
144 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
145 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
150 check_ok = .NOT. nl_hash_table_has_data(hash_table)
152 ALLOCATE (hash_table%obj)
153 NULLIFY (hash_table%obj%table)
154 hash_table%obj%nmax = 0
155 hash_table%obj%nelements = 0
156 hash_table%obj%prime = 2
158 IF (
PRESENT(nmax)) my_nmax = nmax
159 CALL nl_hash_table_init(hash_table=hash_table, nmax=my_nmax)
170 TYPE(nl_hash_table_obj),
INTENT(IN) :: hash_table
171 INTEGER,
INTENT(IN) ::
idx
172 TYPE(neighbor_list_task_type),
INTENT(OUT), &
177 cpassert((
idx .GT. 0) .AND. (
idx .LE. hash_table%obj%nmax))
179 check_ok = nl_hash_table_has_data(hash_table)
182 val => hash_table%obj%table(
idx)%val
191 PURE FUNCTION nl_hash_table_has_data(hash_table)
RESULT(res)
192 TYPE(nl_hash_table_obj),
INTENT(IN) :: hash_table
195 res =
ASSOCIATED(hash_table%obj)
196 END FUNCTION nl_hash_table_has_data
203 SUBROUTINE nl_hash_table_init(hash_table, nmax)
204 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
205 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
207 INTEGER :: ii, my_nmax, two_to_power
210 check_ok = nl_hash_table_has_data(hash_table)
212 my_nmax = hash_table%obj%nmax
213 IF (
PRESENT(nmax)) my_nmax = nmax
218 DO WHILE (two_to_power .LT. my_nmax)
219 two_to_power = 2*two_to_power
221 my_nmax = two_to_power
223 IF (
ASSOCIATED(hash_table%obj%table))
THEN
224 IF (
SIZE(hash_table%obj%table) .NE. my_nmax)
THEN
225 DEALLOCATE (hash_table%obj%table)
226 ALLOCATE (hash_table%obj%table(my_nmax))
229 ALLOCATE (hash_table%obj%table(my_nmax))
231 hash_table%obj%nmax = my_nmax
235 DO ii = 1, hash_table%obj%nmax
236 hash_table%obj%table(ii)%key = empty_key
237 NULLIFY (hash_table%obj%table(ii)%val)
239 hash_table%obj%nelements = 0
240 END SUBROUTINE nl_hash_table_init
249 TYPE(nl_hash_table_obj),
INTENT(IN) :: hash_table
250 INTEGER,
INTENT(IN) :: key
251 LOGICAL,
INTENT(OUT) :: is_null
255 check_ok = nl_hash_table_has_data(hash_table)
257 check_ok = (key .LE. hash_table%obj%nmax)
261 IF (empty_key == hash_table%obj%table(key)%key)
THEN
273 RECURSIVE SUBROUTINE nl_hash_table_rehash(hash_table, nmax)
274 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
275 INTEGER,
INTENT(IN),
OPTIONAL :: nmax
277 INTEGER :: ii, my_nmax
278 TYPE(nl_hash_table_element),
ALLOCATABLE, &
279 DIMENSION(:) :: tmp_table
281 IF (.NOT. nl_hash_table_has_data(hash_table))
THEN
285 IF (
PRESENT(nmax))
THEN
286 my_nmax = max(nmax, hash_table%obj%nelements)
288 my_nmax = hash_table%obj%nmax
290 ALLOCATE (tmp_table(hash_table%obj%nmax))
291 tmp_table(:) = hash_table%obj%table(:)
294 DO ii = 1,
SIZE(tmp_table)
295 IF (tmp_table(ii)%key .NE. empty_key)
THEN
297 key=tmp_table(ii)%key, &
298 val=tmp_table(ii)%val)
301 DEALLOCATE (tmp_table)
302 END SUBROUTINE nl_hash_table_rehash
310 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
312 IF (
ASSOCIATED(hash_table%obj))
THEN
313 IF (
ASSOCIATED(hash_table%obj%table))
THEN
314 DEALLOCATE (hash_table%obj%table)
316 DEALLOCATE (hash_table%obj)
318 NULLIFY (hash_table%obj)
330 TYPE(nl_hash_table_obj),
INTENT(INOUT) :: hash_table
331 INTEGER,
INTENT(OUT),
OPTIONAL :: nelements, nmax, prime
335 check_ok = nl_hash_table_has_data(hash_table)
337 IF (
PRESENT(nelements)) nelements = hash_table%obj%nelements
338 IF (
PRESENT(nmax)) nmax = hash_table%obj%nmax
339 IF (
PRESENT(prime)) prime = hash_table%obj%prime
348 PURE FUNCTION nl_hash_table_linear_probe(hash_table, key)
RESULT(islot)
349 TYPE(nl_hash_table_obj),
INTENT(IN) :: hash_table
350 INTEGER(KIND=int_8),
INTENT(IN) :: key
356 guess = nl_hash_table_hash_function(hash_table, key)
361 DO islot = guess, hash_table%obj%nmax
362 IF ((hash_table%obj%table(islot)%key == key) .OR. &
363 (hash_table%obj%table(islot)%key == empty_key))
RETURN
367 DO islot = 1, guess - 1
368 IF ((hash_table%obj%table(islot)%key == key) .OR. &
369 (hash_table%obj%table(islot)%key == empty_key))
RETURN
374 END FUNCTION nl_hash_table_linear_probe
382 PURE FUNCTION nl_hash_table_hash_function(hash_table, key)
RESULT(hash)
383 TYPE(nl_hash_table_obj),
INTENT(IN) :: hash_table
384 INTEGER(KIND=int_8),
INTENT(IN) :: key
387 INTEGER(KIND=int_8) :: hash_8, nmax_8, prime_8
389 nmax_8 = int(hash_table%obj%nmax,
int_8)
390 prime_8 = int(hash_table%obj%prime,
int_8)
393 hash_8 = iand(key*prime_8, nmax_8 - 1) + 1_int_8
395 END FUNCTION nl_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...
static GRID_HOST_DEVICE int idx(const orbital a)
Return coset index of given orbital angular momentum.
Defines the basic variable types.
integer, parameter, public int_8
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.
Define the neighbor list data types and the corresponding functionality.
A simple hash table of integer keys, using hash function: H(k) = (k*p) mod n + 1 where: k = key p = a...
subroutine, public nl_hash_table_is_null(hash_table, key, is_null)
Initialises a nl_hash_table object.
subroutine, public nl_hash_table_release(hash_table)
releases the hash table. Note that deallocating tasks stored in the table is the responsibility of th...
subroutine, public nl_hash_table_status(hash_table, nelements, nmax, prime)
outputs the current information about the table
recursive subroutine, public nl_hash_table_add(hash_table, key, val)
Add element to a hash table, auto resize if necessary.
subroutine, public nl_hash_table_get_from_index(hash_table, idx, val)
Retrieve value from a hash table given a specified index.
subroutine, public nl_hash_table_create(hash_table, nmax)
Creates and initialises an empty nl_hash_table object.