Neko 1.99.3
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
htable.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
36module htable
37 use num_types, only: dp, i4, i8
38 use utils, only: neko_error
39 use point, only : point_t
41 use math, only : neko_m_ln2
42 use, intrinsic :: iso_c_binding, only : c_ptr, c_associated
43 implicit none
44 private
45
47 type :: h_tuple_t
48 logical :: valid = .false.
49 logical :: skip = .false.
50 class(*), allocatable :: key
51 class(*), allocatable :: data
52 type(h_tuple_t), pointer :: next => null()
53 type(h_tuple_t), pointer :: prev => null()
54 end type h_tuple_t
55
57 type, public, abstract :: htable_t
58 integer, private :: size = 0
59 integer, private :: entries = 0
60 type(h_tuple_t), private, allocatable :: t(:)
61 type(h_tuple_t), pointer :: head => null()
62 type(h_tuple_t), pointer :: tail => null()
63 contains
64 procedure(htable_hash), pass(this), deferred :: hash
65 procedure, public, pass(this) :: clear => htable_clear
66 procedure, public, pass(this) :: free => htable_free
67 procedure, public, pass(this) :: num_entries => htable_num_entries
68 procedure, public, pass(this) :: get_size => htable_size
69 end type htable_t
70
71 abstract interface
72 pure function htable_hash(this, k, c) result(hash)
73 import htable_t
74 class(htable_t), intent(in) :: this
75 class(*), intent(in) :: k
76 integer, value :: c
77 integer :: hash
78 end function htable_hash
79 end interface
80
81 !
82 ! Implementations
83 !
84
86 type, public, extends(htable_t) :: htable_i4_t
87 contains
88 procedure, pass(this) :: init => htable_i4_init
89 procedure, pass(this) :: set => htable_i4_set
90 procedure, pass(this) :: get => htable_i4_get
91 procedure, pass(this) :: hash => htable_i4_hash
92 procedure, pass(this) :: remove => htable_i4_remove
93 end type htable_i4_t
94
96 type, public, extends(htable_t) :: htable_i8_t
97 contains
98 procedure, pass(this) :: init => htable_i8_init
99 procedure, pass(this) :: set => htable_i8_set
100 procedure, pass(this) :: get => htable_i8_get
101 procedure, pass(this) :: hash => htable_i8_hash
102 procedure, pass(this) :: remove => htable_i8_remove
103 end type htable_i8_t
104
106 type, public, extends(htable_t) :: htable_r8_t
107 contains
108 procedure, pass(this) :: init => htable_r8_init
109 procedure, pass(this) :: set => htable_r8_set
110 procedure, pass(this) :: get => htable_r8_get
111 procedure, pass(this) :: hash => htable_r8_hash
112 procedure, pass(this) :: remove => htable_r8_remove
113 end type htable_r8_t
114
116 type, public, extends(htable_t) :: htable_pt_t
117 contains
118 procedure, pass(this) :: init => htable_pt_init
119 procedure, pass(this) :: set => htable_pt_set
120 procedure, pass(this) :: get => htable_pt_get
121 procedure, pass(this) :: hash => htable_pt_hash
122 procedure, pass(this) :: remove => htable_pt_remove
123 end type htable_pt_t
124
126 type, public, extends(htable_t) :: htable_i4t2_t
127 contains
128 procedure, pass(this) :: init => htable_i4t2_init
129 procedure, pass(this) :: set => htable_i4t2_set
130 procedure, pass(this) :: get => htable_i4t2_get
131 procedure, pass(this) :: hash => htable_i4t2_hash
132 procedure, pass(this) :: remove => htable_i4t2_remove
133 end type htable_i4t2_t
134
136 type, public, extends(htable_t) :: htable_i4t4_t
137 contains
138 procedure, pass(this) :: init => htable_i4t4_init
139 procedure, pass(this) :: set => htable_i4t4_set
140 procedure, pass(this) :: get => htable_i4t4_get
141 procedure, pass(this) :: hash => htable_i4t4_hash
142 procedure, pass(this) :: remove => htable_i4t4_remove
143 end type htable_i4t4_t
144
146 type, public, extends(htable_t) :: htable_cptr_t
147 contains
148 procedure, pass(this) :: init => htable_cptr_init
149 procedure, pass(this) :: set => htable_cptr_set
150 procedure, pass(this) :: get => htable_cptr_get
151 procedure, pass(this) :: hash => htable_cptr_hash
152 procedure, pass(this) :: remove => htable_cptr_remove
153 end type htable_cptr_t
154
155 !
156 ! Iterators
157 !
158
160 type, public, abstract :: htable_iter_t
161 class(htable_t), pointer :: t
162 type(h_tuple_t), pointer :: current => null()
163 contains
164 procedure, public, pass(this) :: next => htable_iter_next
165 procedure, public, pass(this) :: reset => htable_iter_reset
166 procedure, public, pass(this) :: data => htable_iter_data
167 end type htable_iter_t
168
170 type, public, extends(htable_iter_t) :: htable_iter_i4_t
171 contains
172 procedure, pass(this) :: init => htable_iter_i4_init
173 procedure, pass(this) :: value => htable_iter_i4_value
174 procedure, pass(this) :: key => htable_iter_i4_key
176 end type htable_iter_i4_t
177
179 type, public, extends(htable_iter_t) :: htable_iter_i8_t
180 contains
181 procedure, pass(this) :: init => htable_iter_i8_init
182 procedure, pass(this) :: value => htable_iter_i8_value
183 procedure, pass(this) :: key => htable_iter_i8_key
185 end type htable_iter_i8_t
186
188 type, public, extends(htable_iter_t) :: htable_iter_r8_t
189 contains
190 procedure, pass(this) :: init => htable_iter_r8_init
191 procedure, pass(this) :: value => htable_iter_r8_value
192 procedure, pass(this) :: key => htable_iter_r8_key
194 end type htable_iter_r8_t
195
197 type, public, extends(htable_iter_t) :: htable_iter_pt_t
198 contains
199 procedure, pass(this) :: init => htable_iter_pt_init
200 procedure, pass(this) :: value => htable_iter_pt_value
201 procedure, pass(this) :: key => htable_iter_pt_key
203 end type htable_iter_pt_t
204
206 type, public, extends(htable_iter_t) :: htable_iter_i4t2_t
207 contains
208 procedure, pass(this) :: init => htable_iter_i4t2_init
209 procedure, pass(this) :: value => htable_iter_i4t2_value
210 procedure, pass(this) :: key => htable_iter_i4t2_key
212 end type htable_iter_i4t2_t
213
215 type, public, extends(htable_iter_t) :: htable_iter_i4t4_t
216 contains
217 procedure, pass(this) :: init => htable_iter_i4t4_init
218 procedure, pass(this) :: value => htable_iter_i4t4_value
219 procedure, pass(this) :: key => htable_iter_i4t4_key
221 end type htable_iter_i4t4_t
222
224 type, public, extends(htable_iter_t) :: htable_iter_cptr_t
225 contains
226 procedure, pass(this) :: init => htable_iter_cptr_init
227 procedure, pass(this) :: value => htable_iter_cptr_value
228 procedure, pass(this) :: key => htable_iter_cptr_key
230 end type htable_iter_cptr_t
231
232 !
233 ! Type wrappers
234 !
235 type, public :: h_cptr_t
236 type(c_ptr) :: ptr
237 end type h_cptr_t
238
239contains
240
242 subroutine htable_init(this, size, key, data)
243 class(htable_t), intent(inout) :: this
244 integer, value :: size
245 class(*), target, intent(in) :: key
246 class(*), target, intent(in), optional :: data
247 class(*), pointer :: data_ptr
248 integer :: i
249
250
251 call htable_free(this)
252
253 if (size .lt. 4) then
254 size = 4
255 end if
256
257 size = ishft(1, ceiling(log(dble(size)) / neko_m_ln2))
258
259 allocate(this%t(0:size))
260 this%t(:)%valid = .false.
261 this%size = size
262 this%entries = 0
263
264 data_ptr => key
265 if (present(data)) then
266 data_ptr => data
267 end if
268
269 do i = 0, size
270 allocate(this%t(i)%key, source=key)
271 allocate(this%t(i)%data, source=data_ptr)
272 end do
273 end subroutine htable_init
274
276 subroutine htable_free(this)
277 class(htable_t), intent(inout) :: this
278 integer :: i
279
280 nullify(this%head)
281 nullify(this%tail)
282
283 if (allocated(this%t)) then
284 do i = 0, this%size
285 deallocate(this%t(i)%key)
286 deallocate(this%t(i)%data)
287 end do
288 deallocate(this%t)
289 end if
290
291 this%size = 0
292 this%entries = 0
293
294 end subroutine htable_free
295
297 subroutine htable_clear(this)
298 class(htable_t), intent(inout) :: this
299
300 if (allocated(this%t)) then
301 this%t(:)%valid = .false.
302 this%entries = 0
303 else
304 call neko_error("Hash table not allocated")
305 end if
306
307 end subroutine htable_clear
308
310 pure function htable_num_entries(this) result(entries)
311 class(htable_t), intent(in) :: this
312 integer :: entries
313 entries = this%entries
314 end function htable_num_entries
315
317 pure function htable_size(this) result(size)
318 class(htable_t), intent(in) :: this
319 integer :: size
320 size = this%size
321 end function htable_size
322
323
325 recursive subroutine htable_set(this, key, data)
326 class(htable_t), target, intent(inout) :: this
327 class(*), intent(inout) :: key
328 class(*), intent(inout) :: data
329 class(htable_t), allocatable :: tmp
330 integer index, i, c
331
332 c = 0
333 i = log(1.0/this%size)/log(0.6)
334 index = 0
335
336 do while (i .ge. 0)
337 index = this%hash(key, c**2)
338 if (index .lt. 0) then
339 call neko_error("Invalid hash generated")
340 end if
342 if ((.not. this%t(index)%valid) .or. &
343 htable_eq_key(this, index, key)) then
344 call htable_set_key(this, index, key)
345 call htable_set_data(this, index, data)
346 if (.not. this%t(index)%valid) then
347 this%entries = this%entries + 1
348 if (associated(this%tail)) then
349 this%tail%next => this%t(index)
350 this%t(index)%prev => this%tail
351 this%tail => this%t(index)
352 else
353 this%head => this%t(index)
354 this%tail => this%t(index)
355 end if
356 end if
357 this%t(index)%valid = .true.
358 this%t(index)%skip = .false.
359 return
360 end if
361 i = i - 1
362 c = c + 1
363 end do
364
365 select type(key)
366 type is (integer)
367 allocate(htable_i4_t::tmp)
368 type is (integer(i8))
369 allocate(htable_i8_t::tmp)
370 type is (double precision)
371 allocate(htable_r8_t::tmp)
372 type is (point_t)
373 allocate(htable_pt_t::tmp)
374 type is (tuple_i4_t)
375 allocate(htable_i4t2_t::tmp)
376 type is (tuple4_i4_t)
377 allocate(htable_i4t4_t::tmp)
378 type is (h_cptr_t)
379 allocate(htable_cptr_t::tmp)
380 class default
381 call neko_error('Invalid htable key')
382 end select
383
384 call htable_init(tmp, ishft(this%size, 1), key, data)
385
386 !
387 ! When rebuilding the table we used the following loop:
388 !
389 ! do i = 0, this%size - 1
390 ! if (this%t(i)%valid) then
391 ! call htable_set(tmp, this%t(i)%key, this%t(i)%data)
392 ! end if
393 ! end do
394 !
395 ! However, CCE 18.x (and probably other llvm based compilers)
396 ! segfault faults unless the data variable is enclosed in a
397 ! select type block
398 !
399
400 do i = 0, this%size - 1
401 if (this%t(i)%valid) then
402 select type (datap => this%t(i)%data)
403 type is (integer)
404 call htable_set(tmp, this%t(i)%key, datap)
405 type is (integer(i8))
406 call htable_set(tmp, this%t(i)%key, datap)
407 type is (double precision)
408 call htable_set(tmp, this%t(i)%key, datap)
409 type is (point_t)
410 call htable_set(tmp, this%t(i)%key, datap)
411 class is (tuple_t)
412 select type(tuplep => datap)
413 type is (tuple_i4_t)
414 call htable_set(tmp, this%t(i)%key, tuplep)
415 type is (tuple4_i4_t)
416 call htable_set(tmp, this%t(i)%key, tuplep)
417 end select
418 type is (h_cptr_t)
419 call htable_set(tmp, this%t(i)%key, datap)
420 class default
421 call neko_error('Invalid htable data')
422 end select
423 end if
424 end do
425
426 this%head => tmp%head
427 this%tail => tmp%tail
428 this%size = tmp%size
429 call move_alloc(tmp%t, this%t)
430
431 call htable_set(this, key, data)
432
433 end subroutine htable_set
434
436 function htable_get(this, key, data) result(rcode)
437 class(htable_t), intent(inout) :: this
438 class(*), intent(inout) :: key
439 class(*), intent(inout) :: data
440 integer :: rcode
441 integer :: index, i, c
442
443 c = 0
444 i = log(1.0/this%size)/log(0.6)
445
446 do while (i .ge. 0)
447 index = this%hash(key, c**2)
448 if (index .lt. 0) then
449 call neko_error("Invalid hash generated")
450 end if
451
452 if (.not. this%t(index)%valid .and. &
453 .not. this%t(index)%skip) then
454 rcode = 1
455 return
456 else if ((this%t(index)%valid) .and. &
457 htable_eq_key(this, index, key)) then
458 call htable_get_data(this, index, data)
459 rcode = 0
460 return
461 end if
462 i = i - 1
463 c = c + 1
464 end do
465 rcode = 1
466 end function htable_get
467
469 subroutine htable_remove(this, key)
470 class(htable_t), intent(inout) :: this
471 class(*), intent(inout) :: key
472 integer :: index, i, c
473
474 c = 0
475 i = log(1.0/this%size)/log(0.6)
476
477 do while (i .ge. 0)
478 index = this%hash(key, c**2)
479 if (index .lt. 0) then
480 call neko_error("Invalid hash generated")
481 end if
482
483 if ((this%t(index)%valid) .and. &
484 htable_eq_key(this, index, key)) then
485
486 if (associated(this%t(index)%prev)) then
487 this%t(index)%prev%next => this%t(index)%next
488 else
489 this%head => this%t(index)%next
490 end if
491
492 if (associated(this%t(index)%next)) then
493 this%t(index)%next%prev => this%t(index)%prev
494 else
495 this%tail => this%t(index)%prev
496 end if
497
498 this%t(index)%valid = .false.
499 this%t(index)%skip = .true.
500 this%entries = this%entries - 1
501 return
502 end if
503 i = i - 1
504 c = c + 1
505 end do
506 end subroutine htable_remove
507
509 subroutine htable_set_data(this, idx, data)
510 class(htable_t), target, intent(inout) :: this
511 integer, intent(in) :: idx
512 class(*), intent(in) :: data
513 class(*), pointer :: hdp
514
515 hdp => this%t(idx)%data
516 select type (data)
517 type is (integer)
518 select type(hdp)
519 type is (integer)
520 hdp = data
521 end select
522 type is (integer(i8))
523 select type(hdp)
524 type is (integer(i8))
525 hdp = data
526 end select
527 type is (double precision)
528 select type(hdp)
529 type is (double precision)
530 hdp = data
531 end select
532 type is (point_t)
533 select type(hdp)
534 type is (point_t)
535 hdp = data
536 end select
537 class is (tuple_t)
538 select type(hdp)
539 type is (tuple_i4_t)
540 hdp = data
541 type is (tuple4_i4_t)
542 hdp = data
543 end select
544 type is (h_cptr_t)
545 select type(hdp)
546 type is (h_cptr_t)
547 hdp = data
548 end select
549 class default
550 call neko_error('Invalid htable data (set)')
551 end select
552 end subroutine htable_set_data
553
555 subroutine htable_get_data(this, idx, data)
556 class(htable_t), intent(in) :: this
557 integer, intent(in) :: idx
558 class(*), intent(inout) :: data
559
560 select type (hdp=>this%t(idx)%data)
561 type is (integer)
562 select type(data)
563 type is (integer)
564 data = hdp
565 end select
566 type is (integer(i8))
567 select type(data)
568 type is (integer(i8))
569 data = hdp
570 end select
571 type is (double precision)
572 select type(data)
573 type is (double precision)
574 data = hdp
575 end select
576 type is (point_t)
577 select type(data)
578 type is (point_t)
579 data = hdp
580 end select
581 class is (tuple_t)
582 select type(data)
583 type is (tuple_i4_t)
584 data = hdp
585 type is (tuple4_i4_t)
586 data = hdp
587 end select
588 type is (h_cptr_t)
589 select type (data)
590 type is (h_cptr_t)
591 data = hdp
592 end select
593 class default
594 call neko_error('Invalid htable data (get)')
595 end select
596 end subroutine htable_get_data
597
599 pure function htable_eq_key(this, idx, key) result(res)
600 class(htable_t), intent(in) :: this
601 integer, intent(in) :: idx
602 class(*), intent(in) :: key
603 logical :: res
604
605 res = .true.
606 select type (kp=>this%t(idx)%key)
607 type is (integer)
608 select type(key)
609 type is (integer)
610 res = (kp .eq. key)
611 end select
612 type is (integer(i8))
613 select type(key)
614 type is (integer(i8))
615 res = (kp .eq. key)
616 end select
617 type is (double precision)
618 select type(key)
619 type is (double precision)
620 res = abs(kp - key) .lt. epsilon(1.0_dp)
621 end select
622 type is (point_t)
623 select type (key)
624 type is (point_t)
625 res = (kp .eq. key)
626 end select
627 class is (tuple_t)
628 select type (key)
629 type is (tuple_i4_t)
630 res = (key .eq. kp)
631 type is (tuple4_i4_t)
632 res = (key .eq. kp)
633 end select
634 type is (h_cptr_t)
635 select type (key)
636 type is (h_cptr_t)
637 res = c_associated(kp%ptr, key%ptr)
638 end select
639 end select
640 end function htable_eq_key
641
643 subroutine htable_set_key(this, idx, key)
644 class(htable_t), target, intent(inout) :: this
645 integer, intent(in) :: idx
646 class(*), intent(in) :: key
647 class(*), pointer :: kp
648
649 kp => this%t(idx)%key
650 select type(key)
651 type is (integer)
652 select type(kp)
653 type is (integer)
654 kp = key
655 end select
656 type is (integer(i8))
657 select type(kp)
658 type is (integer(i8))
659 kp = key
660 end select
661 type is (double precision)
662 select type(kp)
663 type is (double precision)
664 kp = key
665 end select
666 type is (point_t)
667 select type (kp)
668 type is (point_t)
669 kp = key
670 end select
671 class is (tuple_t)
672 select type(kp)
673 type is (tuple_i4_t)
674 kp = key
675 type is (tuple4_i4_t)
676 kp = key
677 end select
678 type is (h_cptr_t)
679 select type(kp)
680 type is (h_cptr_t)
681 kp = key
682 end select
683 class default
684 call neko_error('Invalid htable key (set)')
685 end select
686 end subroutine htable_set_key
687
689 function htable_iter_next(this) result(valid)
690 class(htable_iter_t), target, intent(inout) :: this
691 logical :: valid
692
693 if (.not. associated(this%current)) then
694 this%current => this%t%head
695 valid = associated(this%current)
696 else if (associated(this%current)) then
697 if (associated(this%current, this%t%tail)) then
698 valid = .false.
699 else
700 this%current => this%current%next
701 valid = associated(this%current)
702 end if
703 end if
704
705 end function htable_iter_next
706
708 subroutine htable_iter_reset(this)
709 class(htable_iter_t), intent(inout) :: this
710 nullify(this%current)
711 end subroutine htable_iter_reset
712
717 subroutine htable_iter_data(this, data)
718 class(htable_iter_t), target, intent(inout) :: this
719 class(*), intent(inout) :: data
720 class(*), pointer :: hdp
721
722 hdp => this%current%data
723 select type(hdp)
724 type is (integer)
725 select type (data)
726 type is (integer)
727 data = hdp
728 end select
729 type is (integer(i8))
730 select type (data)
731 type is (integer(i8))
732 data = hdp
733 end select
734 type is (double precision)
735 select type(data)
736 type is (double precision)
737 data = hdp
738 end select
739 type is (point_t)
740 select type (data)
741 type is (point_t)
742 data = hdp
743 end select
744 class is (tuple_t)
745 select type (data)
746 type is (tuple_i4_t)
747 data = hdp
748 type is (tuple4_i4_t)
749 data = hdp
750 end select
751 type is (h_cptr_t)
752 select type (data)
753 type is (h_cptr_t)
754 data = hdp
755 end select
756 class default
757 call neko_error('Invalid htable data (iter)')
758 end select
759
760 end subroutine htable_iter_data
761
762 !
763 ! Integer based implementation
764 !
766 subroutine htable_i4_init(this, size, data)
767 class(htable_i4_t), intent(inout) :: this
768 integer, value :: size
769 class(*), intent(inout), optional :: data
770 integer :: key
771
772 if (present(data)) then
773 call htable_init(this, size, key, data)
774 else
775 call htable_init(this, size, key)
776 end if
777
778 end subroutine htable_i4_init
779
781 subroutine htable_i4_set(this, key, data)
782 class(htable_i4_t), intent(inout) :: this
783 integer, intent(inout) :: key
784 class(*), intent(inout) :: data
785
786 call htable_set(this, key, data)
787
788 end subroutine htable_i4_set
789
791 function htable_i4_get(this, key, data) result(rcode)
792 class(htable_i4_t), intent(inout) :: this
793 integer, intent(inout) :: key
794 class(*), intent(inout) :: data
795 integer :: rcode
796
797 rcode = htable_get(this, key, data)
798
799 end function htable_i4_get
800
802 pure function htable_i4_hash(this, k, c) result(hash)
803 class(htable_i4_t), intent(in) :: this
804 class(*), intent(in) :: k
805 integer, value :: c
806 integer :: hash
807 integer(kind=i8) :: tmp
808 integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
809 integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
810 integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
811 integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
812 integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
813 integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
814
815 select type(k)
816 type is (integer)
817 tmp = int(k, i8)
818 tmp = (k + m1) + ishft(k, 12)
819 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
820 tmp = (tmp + m3) + ishft(tmp, 5)
821 tmp = ieor((tmp + m4), ishft(tmp, 9))
822 tmp = (tmp + m5) + ishft(tmp, 3)
823 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
824 tmp = modulo(tmp + int(c, i8), int(this%size, i8))
825 hash = int(tmp, i4)
826 class default
827 hash = -1
828 end select
829 end function htable_i4_hash
830
832 subroutine htable_i4_remove(this, key)
833 class(htable_i4_t), intent(inout) :: this
834 integer, intent(inout) :: key
835
836 call htable_remove(this, key)
837
838 end subroutine htable_i4_remove
839
841 subroutine htable_iter_i4_init(this, t)
842 class(htable_iter_i4_t), intent(inout) :: this
843 type(htable_i4_t), target, intent(inout) :: t
844
845 this%t => t
846
847 end subroutine htable_iter_i4_init
848
850 subroutine htable_iter_i4_free(this)
851 type(htable_iter_i4_t), intent(inout) :: this
852 nullify(this%t)
853 nullify(this%current)
854 end subroutine htable_iter_i4_free
855
857 function htable_iter_i4_value(this) result(value)
858 class(htable_iter_i4_t), target, intent(inout) :: this
859 integer, pointer :: value
860
861 select type (hdp => this%current%data)
862 type is (integer)
863 value => hdp
864 class default
865 call neko_error('Key and data of different kind (i4)')
866 end select
867
868 end function htable_iter_i4_value
869
871 function htable_iter_i4_key(this) result(key)
872 class(htable_iter_i4_t), target, intent(inout) :: this
873 integer, pointer :: key
874
875 select type (kp => this%current%key)
876 type is (integer)
877 key => kp
878 class default
879 call neko_error('Invalid key (i4)')
880 end select
881
882 end function htable_iter_i4_key
883
884 !
885 ! Integer*8 based implementation
886 !
888 subroutine htable_i8_init(this, size, data)
889 class(htable_i8_t), intent(inout) :: this
890 integer, value :: size
891 class(*), intent(inout), optional :: data
892 integer(kind=i8) :: key
893
894 if (present(data)) then
895 call htable_init(this, size, key, data)
896 else
897 call htable_init(this, size, key)
898 end if
899
900 end subroutine htable_i8_init
901
903 subroutine htable_i8_set(this, key, data)
904 class(htable_i8_t), intent(inout) :: this
905 integer(kind=i8), intent(inout) :: key
906 class(*), intent(inout) :: data
907
908 call htable_set(this, key, data)
909
910 end subroutine htable_i8_set
911
913 function htable_i8_get(this, key, data) result(rcode)
914 class(htable_i8_t), intent(inout) :: this
915 integer(kind=i8), intent(inout) :: key
916 class(*), intent(inout) :: data
917 integer :: rcode
918
919 rcode = htable_get(this, key, data)
920
921 end function htable_i8_get
922
924 pure function htable_i8_hash(this, k, c) result(hash)
925 class(htable_i8_t), intent(in) :: this
926 class(*), intent(in) :: k
927 integer, value :: c
928 integer :: hash
929 integer(kind=i8) :: tmp
930 integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
931 integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
932 integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
933 integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
934 integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
935 integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
936
937 select type(k)
938 type is (integer(i8))
939 tmp = (k + m1) + ishft(k, 12)
940 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
941 tmp = (tmp + m3) + ishft(tmp, 5)
942 tmp = ieor((tmp + m4), ishft(tmp, 9))
943 tmp = (tmp + m5) + ishft(tmp, 3)
944 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
945 hash = int(modulo(tmp, int(this%size, i8)), i4)
947 hash = int(modulo((k * 2654435761_i8) + int(c, i8), &
948 int(this%size, i8)), i4)
949 class default
950 hash = -1
951 end select
952 end function htable_i8_hash
953
955 subroutine htable_i8_remove(this, key)
956 class(htable_i8_t), intent(inout) :: this
957 integer(kind=i8), intent(inout) :: key
958
959 call htable_remove(this, key)
960
961 end subroutine htable_i8_remove
962
964 subroutine htable_iter_i8_init(this, t)
965 class(htable_iter_i8_t), intent(inout) :: this
966 type(htable_i8_t), target, intent(inout) :: t
967
968 this%t => t
969
970 end subroutine htable_iter_i8_init
971
973 subroutine htable_iter_i8_free(this)
974 type(htable_iter_i8_t), intent(inout) :: this
975 nullify(this%t)
976 nullify(this%current)
977 end subroutine htable_iter_i8_free
978
980 function htable_iter_i8_value(this) result(value)
981 class(htable_iter_i8_t), target, intent(inout) :: this
982 integer(kind=i8), pointer :: value
983
984 select type (hdp => this%current%data)
985 type is (integer(i8))
986 value => hdp
987 class default
988 call neko_error('Key and data of different kind (i8)')
989 end select
990
991 end function htable_iter_i8_value
992
994 function htable_iter_i8_key(this) result(key)
995 class(htable_iter_i8_t), target, intent(inout) :: this
996 integer(kind=i8), pointer :: key
997
998 ! We should not need this extra select block, and it works great
999 ! without it for GNU, Intel and NEC, but breaks horribly on Cray
1000 ! (>11.0.x) when using high opt. levels.
1001 select type(hti => this)
1002 type is(htable_iter_i8_t)
1003 select type (kp => hti%current%key)
1004 type is (integer(i8))
1005 key => kp
1006 class default
1007 call neko_error('Invalid key (i8)')
1008 end select
1009 class default
1010 call neko_error('Corrupt htable iter. (i8)')
1011 end select
1012
1013 end function htable_iter_i8_key
1014
1015
1016 !
1017 ! Double precision based implementation
1018 !
1020 subroutine htable_r8_init(this, size, data)
1021 class(htable_r8_t), intent(inout) :: this
1022 integer, value :: size
1023 class(*), intent(inout), optional :: data
1024 real(kind=dp) :: key
1025
1026 if (present(data)) then
1027 call htable_init(this, size, key, data)
1028 else
1029 call htable_init(this, size, key)
1030 end if
1031
1032 end subroutine htable_r8_init
1033
1035 subroutine htable_r8_set(this, key, data)
1036 class(htable_r8_t), intent(inout) :: this
1037 real(kind=dp), intent(inout) :: key
1038 class(*), intent(inout) :: data
1039
1040 call htable_set(this, key, data)
1041
1042 end subroutine htable_r8_set
1043
1045 function htable_r8_get(this, key, data) result(rcode)
1046 class(htable_r8_t), intent(inout) :: this
1047 real(kind=dp), intent(inout) :: key
1048 class(*), intent(inout) :: data
1049 integer :: rcode
1050
1051 rcode = htable_get(this, key, data)
1052
1053 end function htable_r8_get
1054
1056 pure function htable_r8_hash(this, k, c) result(hash)
1057 class(htable_r8_t), intent(in) :: this
1058 class(*), intent(in) :: k
1059 integer, value :: c
1060 integer :: hash
1061 select type(k)
1062 type is (double precision)
1063 hash = modulo(floor((2d0 * abs(fraction(k)) - 1d0) * 2**16) + c, this%size)
1064 class default
1065 hash = -1
1066 end select
1067 end function htable_r8_hash
1068
1070 subroutine htable_r8_remove(this, key)
1071 class(htable_r8_t), intent(inout) :: this
1072 real(kind=dp), intent(inout) :: key
1073
1074 call htable_remove(this, key)
1075
1076 end subroutine htable_r8_remove
1077
1078
1080 subroutine htable_iter_r8_init(this, t)
1081 class(htable_iter_r8_t), intent(inout) :: this
1082 type(htable_r8_t), target, intent(inout) :: t
1083
1084 this%t => t
1085
1086 end subroutine htable_iter_r8_init
1087
1089 subroutine htable_iter_r8_free(this)
1090 type(htable_iter_r8_t), intent(inout) :: this
1091 nullify(this%t)
1092 nullify(this%current)
1093 end subroutine htable_iter_r8_free
1094
1096 function htable_iter_r8_value(this) result(value)
1097 class(htable_iter_r8_t), target, intent(inout) :: this
1098 real(kind=dp), pointer :: value
1099
1100 select type (hdp => this%current%data)
1101 type is (double precision)
1102 value => hdp
1103 class default
1104 call neko_error('Key and data of different kind (r8)')
1105 end select
1106
1107 end function htable_iter_r8_value
1108
1110 function htable_iter_r8_key(this) result(key)
1111 class(htable_iter_r8_t), target, intent(inout) :: this
1112 real(kind=dp), pointer :: key
1113
1114 select type (kp => this%current%key)
1115 type is (double precision)
1116 key => kp
1117 class default
1118 call neko_error('Invalid key (r8)')
1119 end select
1120
1121 end function htable_iter_r8_key
1122
1123 !
1124 ! Point based implementation
1125 !
1127 subroutine htable_pt_init(this, size, data)
1128 class(htable_pt_t), intent(inout) :: this
1129 integer, value :: size
1130 class(*), intent(inout), optional :: data
1131 type(point_t) :: key
1132
1133 if (present(data)) then
1134 call htable_init(this, size, key, data)
1135 else
1136 call htable_init(this, size, key)
1137 end if
1138
1139 end subroutine htable_pt_init
1140
1142 subroutine htable_pt_set(this, key, data)
1143 class(htable_pt_t), intent(inout) :: this
1144 type(point_t), intent(inout) :: key
1145 class(*), intent(inout) :: data
1146
1147 call htable_set(this, key, data)
1148
1149 end subroutine htable_pt_set
1150
1152 function htable_pt_get(this, key, data) result(rcode)
1153 class(htable_pt_t), intent(inout) :: this
1154 type(point_t), intent(inout) :: key
1155 class(*), intent(inout) :: data
1156 integer :: rcode
1157
1158 rcode = htable_get(this, key, data)
1159
1160 end function htable_pt_get
1161
1163 pure function htable_pt_hash(this, k, c) result(hash)
1164 class(htable_pt_t), intent(in) :: this
1165 class(*), intent(in) :: k
1166 integer, value :: c
1167 integer :: hash, i
1168 integer(kind=i8) :: hash2, tmp, mult
1169 integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1170 integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1171 integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1172 integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1173 integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1174 integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1175
1176 select type(k)
1177 type is (point_t)
1178 mult = 1000003
1179 hash2 = int(z'345678')
1180 do i = 1, 3
1181 tmp = transfer(k%x(i), tmp)
1182 tmp = (tmp + m1) + ishft(tmp, 12)
1183 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1184 tmp = (tmp + m3) + ishft(tmp, 5)
1185 tmp = ieor((tmp + m4), ishft(tmp, 9))
1186 tmp = (tmp + m5) + ishft(tmp, 3)
1187 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1188 hash2 = ieor(hash2, tmp) * mult
1189 mult = mult + 82520 + 8
1190 end do
1191 hash2 = hash2 + 97531
1192 hash2 = modulo(hash2 + int(c, i8), int(this%size,i8))
1193 hash = int(hash2, i4)
1194 class default
1195 hash = -1
1196 end select
1197
1198 end function htable_pt_hash
1199
1201 subroutine htable_pt_remove(this, key)
1202 class(htable_pt_t), intent(inout) :: this
1203 type(point_t), intent(inout) :: key
1204
1205 call htable_remove(this, key)
1206
1207 end subroutine htable_pt_remove
1208
1209
1211 subroutine htable_iter_pt_init(this, t)
1212 class(htable_iter_pt_t), intent(inout) :: this
1213 type(htable_pt_t), target, intent(inout) :: t
1214
1215 this%t => t
1216
1217 end subroutine htable_iter_pt_init
1218
1220 subroutine htable_iter_pt_free(this)
1221 type(htable_iter_pt_t), intent(inout) :: this
1222 nullify(this%t)
1223 nullify(this%current)
1224 end subroutine htable_iter_pt_free
1225
1227 function htable_iter_pt_value(this) result(value)
1228 class(htable_iter_pt_t), target, intent(inout) :: this
1229 type(point_t), pointer :: value
1230
1231 select type (hdp => this%current%data)
1232 type is (point_t)
1233 value => hdp
1234 class default
1235 call neko_error('Key and data of different kind (pt)')
1236 end select
1237
1238 end function htable_iter_pt_value
1239
1241 function htable_iter_pt_key(this) result(key)
1242 class(htable_iter_pt_t), target, intent(inout) :: this
1243 type(point_t), pointer :: key
1244
1245 select type (kp => this%current%key)
1246 type is (point_t)
1247 key => kp
1248 class default
1249 call neko_error('Invalid key (pt)')
1250 end select
1251
1252 end function htable_iter_pt_key
1253
1254 !
1255 ! Integer 2-tuple based implementation
1256 !
1258 subroutine htable_i4t2_init(this, size, data)
1259 class(htable_i4t2_t), intent(inout) :: this
1260 integer, value :: size
1261 class(*), intent(inout), optional :: data
1262 type(tuple_i4_t) :: key
1263
1264 if (present(data)) then
1265 call htable_init(this, size, key, data)
1266 else
1267 call htable_init(this, size, key)
1268 end if
1269
1270 end subroutine htable_i4t2_init
1271
1273 subroutine htable_i4t2_set(this, key, data)
1274 class(htable_i4t2_t), intent(inout) :: this
1275 type(tuple_i4_t), intent(inout) :: key
1276 class(*), intent(inout) :: data
1277
1278 call htable_set(this, key, data)
1279
1280 end subroutine htable_i4t2_set
1281
1283 function htable_i4t2_get(this, key, data) result(rcode)
1284 class(htable_i4t2_t), intent(inout) :: this
1285 type(tuple_i4_t), intent(inout) :: key
1286 class(*), intent(inout) :: data
1287 integer :: rcode
1288
1289 rcode = htable_get(this, key, data)
1290
1291 end function htable_i4t2_get
1292
1294 pure function htable_i4t2_hash(this, k, c) result(hash)
1295 class(htable_i4t2_t), intent(in) :: this
1296 class(*), intent(in) :: k
1297 integer, value :: c
1298 integer :: i, hash
1299 integer(kind=i8) :: tmp, hash2, mult
1300 integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1301 integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1302 integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1303 integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1304 integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1305 integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1306
1307 select type(k)
1308 type is (tuple_i4_t)
1309 mult = int(1000003, i8)
1310 hash2 = int(z'345678', i8)
1311 do i = 1, 2
1312 tmp = int(k%x(i), i8)
1313 tmp = (tmp + m1) + ishft(tmp, 12)
1314 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1315 tmp = (tmp + m3) + ishft(tmp, 5)
1316 tmp = ieor((tmp + m4), ishft(tmp, 9))
1317 tmp = (tmp + m5) + ishft(tmp, 3)
1318 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1319 hash2 = ieor(hash2, tmp) * mult
1320 mult = mult + 82520_i8 + 4_i8
1321 end do
1322 hash2 = hash2 + 97531_i8
1323 hash2 = modulo(hash2 + int(c, i8), int(this%size, i8))
1324 hash = int(hash2, i4)
1325 class default
1326 hash = -1
1327 end select
1328 end function htable_i4t2_hash
1329
1331 subroutine htable_i4t2_remove(this, key)
1332 class(htable_i4t2_t), intent(inout) :: this
1333 type(tuple_i4_t), intent(inout) :: key
1334
1335 call htable_remove(this, key)
1336
1337 end subroutine htable_i4t2_remove
1338
1340 subroutine htable_iter_i4t2_init(this, t)
1341 class(htable_iter_i4t2_t), intent(inout) :: this
1342 type(htable_i4t2_t), target, intent(inout) :: t
1343
1344 this%t => t
1345
1346 end subroutine htable_iter_i4t2_init
1347
1349 subroutine htable_iter_i4t2_free(this)
1350 type(htable_iter_i4t2_t), intent(inout) :: this
1351 nullify(this%t)
1352 nullify(this%current)
1353 end subroutine htable_iter_i4t2_free
1354
1356 function htable_iter_i4t2_value(this) result(value)
1357 class(htable_iter_i4t2_t), intent(inout) :: this
1358 type(tuple_i4_t), pointer :: value
1359
1360 select type (hdp => this%current%data)
1361 type is (tuple_i4_t)
1362 value => hdp
1363 class default
1364 call neko_error('Key and data of different kind (i4t2)')
1365 end select
1366
1367 end function htable_iter_i4t2_value
1368
1370 function htable_iter_i4t2_key(this) result(key)
1371 class(htable_iter_i4t2_t), intent(inout) :: this
1372 type(tuple_i4_t), pointer :: key
1373
1374 select type (kp => this%current%key)
1375 type is (tuple_i4_t)
1376 key => kp
1377 class default
1378 call neko_error('Invalid key (i4t2)')
1379 end select
1380
1381 end function htable_iter_i4t2_key
1382
1383 !
1384 ! Integer 4-tuple based implementation
1385 !
1387 subroutine htable_i4t4_init(this, size, data)
1388 class(htable_i4t4_t), intent(inout) :: this
1389 integer, value :: size
1390 class(*), intent(inout), optional :: data
1391 type(tuple4_i4_t) :: key
1392
1393 if (present(data)) then
1394 call htable_init(this, size, key, data)
1395 else
1396 call htable_init(this, size, key)
1397 end if
1398
1399 end subroutine htable_i4t4_init
1400
1402 subroutine htable_i4t4_set(this, key, data)
1403 class(htable_i4t4_t), intent(inout) :: this
1404 type(tuple4_i4_t), intent(inout) :: key
1405 class(*), intent(inout) :: data
1406
1407 call htable_set(this, key, data)
1408
1409 end subroutine htable_i4t4_set
1410
1412 function htable_i4t4_get(this, key, data) result(rcode)
1413 class(htable_i4t4_t), intent(inout) :: this
1414 type(tuple4_i4_t), intent(inout) :: key
1415 class(*), intent(inout) :: data
1416 integer :: rcode
1417
1418 rcode = htable_get(this, key, data)
1419
1420 end function htable_i4t4_get
1421
1423 pure function htable_i4t4_hash(this, k, c) result(hash)
1424 class(htable_i4t4_t), intent(in) :: this
1425 class(*), intent(in) :: k
1426 integer, value :: c
1427 integer :: i, hash
1428 integer(kind=i8) :: tmp, hash2, mult
1429 integer(kind=i8), parameter :: m1 = int(z'7ed55d15', i8)
1430 integer(kind=i8), parameter :: m2 = int(z'c761c23c', i8)
1431 integer(kind=i8), parameter :: m3 = int(z'165667b1', i8)
1432 integer(kind=i8), parameter :: m4 = int(z'd3a2646c', i8)
1433 integer(kind=i8), parameter :: m5 = int(z'fd7046c5', i8)
1434 integer(kind=i8), parameter :: m6 = int(z'b55a4f09', i8)
1435
1436 select type(k)
1437 type is (tuple4_i4_t)
1438 mult = int(1000003, i8)
1439 hash2 = int(z'345678', i8)
1440 do i = 1, 4
1441 tmp = int(k%x(i), i8)
1442 tmp = (tmp + m1) + ishft(tmp, 12)
1443 tmp = ieor(ieor(tmp, m2), ishft(tmp, -19))
1444 tmp = (tmp + m3) + ishft(tmp, 5)
1445 tmp = ieor((tmp + m4), ishft(tmp, 9))
1446 tmp = (tmp + m5) + ishft(tmp, 3)
1447 tmp = ieor(ieor(tmp, m6), ishft(tmp, -16))
1448 hash2 = ieor(hash2, tmp) * mult
1449 mult = mult + 82520_i8 + 8_i8
1450 end do
1451 hash2 = hash2 + 97531_i8
1452 hash2 = modulo(hash2 + int(c, i8), int(this%size, i8))
1453 hash = int(hash2, i4)
1454 class default
1455 hash = -1
1456 end select
1457 end function htable_i4t4_hash
1458
1460 subroutine htable_i4t4_remove(this, key)
1461 class(htable_i4t4_t), intent(inout) :: this
1462 type(tuple4_i4_t), intent(inout) :: key
1463
1464 call htable_remove(this, key)
1465
1466 end subroutine htable_i4t4_remove
1467
1469 subroutine htable_iter_i4t4_init(this, t)
1470 class(htable_iter_i4t4_t), intent(inout) :: this
1471 type(htable_i4t4_t), target, intent(inout) :: t
1472
1473 this%t => t
1474
1475 end subroutine htable_iter_i4t4_init
1476
1478 subroutine htable_iter_i4t4_free(this)
1479 type(htable_iter_i4t4_t), intent(inout) :: this
1480 nullify(this%t)
1481 nullify(this%current)
1482 end subroutine htable_iter_i4t4_free
1483
1485 function htable_iter_i4t4_value(this) result(value)
1486 class(htable_iter_i4t4_t), target, intent(inout) :: this
1487 type(tuple4_i4_t), pointer :: value
1488
1489 select type (hdp => this%current%data)
1490 type is (tuple4_i4_t)
1491 value => hdp
1492 class default
1493 call neko_error('Key and data of different kind (i4t4)')
1494 end select
1495
1496 end function htable_iter_i4t4_value
1497
1499 function htable_iter_i4t4_key(this) result(key)
1500 class(htable_iter_i4t4_t), target, intent(inout) :: this
1501 type(tuple4_i4_t), pointer :: key
1502
1503 ! We should not need this extra select block, and it works great
1504 ! without it for GNU, Intel and NEC, but breaks horribly on Cray
1505 ! (>11.0.x) when using high opt. levels.
1506 select type(hti => this)
1507 type is(htable_iter_i4t4_t)
1508 select type (kp => hti%current%key)
1509 type is (tuple4_i4_t)
1510 key => kp
1511 class default
1512 call neko_error('Invalid key (i4t4)')
1513 end select
1514 class default
1515 call neko_error('Corrupt htable iter. (i4t4)')
1516 end select
1517
1518 end function htable_iter_i4t4_key
1519
1520 !
1521 ! C pointer based implementation
1522 !
1524 subroutine htable_cptr_init(this, size, data)
1525 class(htable_cptr_t), intent(inout) :: this
1526 integer, value :: size
1527 class(*), intent(inout), optional :: data
1528 type(h_cptr_t) :: key
1529
1530 if (present(data)) then
1531 call htable_init(this, size, key, data)
1532 else
1533 call htable_init(this, size, key)
1534 end if
1535
1536 end subroutine htable_cptr_init
1537
1539 subroutine htable_cptr_set(this, key, data)
1540 class(htable_cptr_t), target, intent(inout) :: this
1541 type(h_cptr_t), intent(inout) :: key
1542 class(*), intent(inout) :: data
1543
1544 call htable_set(this, key, data)
1545
1546 end subroutine htable_cptr_set
1547
1549 function htable_cptr_get(this, key, data) result(rcode)
1550 class(htable_cptr_t), target, intent(inout) :: this
1551 type(h_cptr_t), intent(inout) :: key
1552 class(*), intent(inout) :: data
1553 integer :: rcode
1554
1555 rcode = htable_get(this, key, data)
1556
1557 end function htable_cptr_get
1558
1560 pure function htable_cptr_hash(this, k, c) result(hash)
1561 class(htable_cptr_t), intent(in) :: this
1562 class(*), intent(in) :: k
1563 integer, value :: c
1564 integer :: hash
1565 integer(kind=i8) :: k_int
1566
1567 select type(k)
1568 type is (h_cptr_t)
1569 k_int = transfer(k%ptr, k_int)
1570 hash = int(modulo(k_int * 2654435761_i8 + int(c, i8),&
1571 int(this%size, i8)), i4)
1572 class default
1573 hash = -1
1574 end select
1575 end function htable_cptr_hash
1576
1578 subroutine htable_cptr_remove(this, key)
1579 class(htable_cptr_t), target, intent(inout) :: this
1580 type(h_cptr_t), intent(inout) :: key
1581
1582 call htable_remove(this, key)
1583
1584 end subroutine htable_cptr_remove
1585
1587 subroutine htable_iter_cptr_init(this, t)
1588 class(htable_iter_cptr_t), intent(inout) :: this
1589 type(htable_cptr_t), target, intent(inout) :: t
1590
1591 this%t => t
1592
1593 end subroutine htable_iter_cptr_init
1594
1596 subroutine htable_iter_cptr_free(this)
1597 type(htable_iter_cptr_t), intent(inout) :: this
1598 nullify(this%t)
1599 nullify(this%current)
1600 end subroutine htable_iter_cptr_free
1601
1603 function htable_iter_cptr_value(this) result(value)
1604 class(htable_iter_cptr_t), target, intent(inout) :: this
1605 class(*), pointer :: hdp
1606 type(h_cptr_t), pointer :: value
1607
1608 hdp => this%current%data
1609 select type (hdp)
1610 type is (h_cptr_t)
1611 value => hdp
1612 class default
1613 call neko_error('Key and data of different kind (cptr)')
1614 end select
1615
1616 end function htable_iter_cptr_value
1617
1619 function htable_iter_cptr_key(this) result(key)
1620 class(htable_iter_cptr_t), target, intent(inout) :: this
1621 class(*), pointer :: kp
1622 type(h_cptr_t), pointer :: key
1623
1624 kp => this%current%key
1625 select type (kp)
1626 type is (h_cptr_t)
1627 key => kp
1628 class default
1629 call neko_error('Invalid key (cptr)')
1630 end select
1631
1632 end function htable_iter_cptr_key
1633
1634end module htable
Implements a hash table ADT.
Definition htable.f90:36
subroutine htable_i4t4_init(this, size, data)
Initialize an integer 4-tuple hash table.
Definition htable.f90:1388
subroutine htable_iter_r8_init(this, t)
Initialize a double precision based hash table iterator.
Definition htable.f90:1081
subroutine htable_clear(this)
Clear all entries in a hash table.
Definition htable.f90:298
subroutine htable_pt_init(this, size, data)
Initialize a point based hash table.
Definition htable.f90:1128
type(tuple_i4_t) function, pointer htable_iter_i4t2_key(this)
Return the current key of integer based 2-tuple hash table iterator.
Definition htable.f90:1371
subroutine htable_iter_i8_free(this)
Destroy an integer*8 based hash table iterator.
Definition htable.f90:974
subroutine htable_i4_set(this, key, data)
Insert an integer into the hash table.
Definition htable.f90:782
type(tuple4_i4_t) function, pointer htable_iter_i4t4_value(this)
Return the current value of integer based 4-tuple hash table iterator.
Definition htable.f90:1486
integer function, pointer htable_iter_i4_value(this)
Return the current value of the integer based hash table iterator.
Definition htable.f90:858
subroutine htable_r8_init(this, size, data)
Initialize a double precision based hash table.
Definition htable.f90:1021
integer(kind=i8) function, pointer htable_iter_i8_key(this)
Return the current key of the integer*8 based hash table iterator.
Definition htable.f90:995
type(point_t) function, pointer htable_iter_pt_key(this)
Return the current key of the point based hash table iterator.
Definition htable.f90:1242
pure integer function htable_r8_hash(this, k, c)
Hash function for a double precision based hash table.
Definition htable.f90:1057
subroutine htable_cptr_init(this, size, data)
Initialize a C pointer based hash table.
Definition htable.f90:1525
pure integer function htable_i4_hash(this, k, c)
Hash function for an integer based hash table.
Definition htable.f90:803
subroutine htable_iter_cptr_free(this)
Destroy a C pointer based hash table iterator.
Definition htable.f90:1597
subroutine htable_iter_pt_free(this)
Destroy a point based hash table iterator.
Definition htable.f90:1221
subroutine htable_i4t4_set(this, key, data)
Insert an integer 4-tuple into the hash table.
Definition htable.f90:1403
subroutine htable_i8_init(this, size, data)
Initialize an integer*8 based hash table.
Definition htable.f90:889
subroutine htable_pt_remove(this, key)
Remove a point with key key from the hash table.
Definition htable.f90:1202
subroutine htable_cptr_remove(this, key)
Remove a C pointer with key key from the hash table.
Definition htable.f90:1579
subroutine htable_free(this)
Destroy a hash table.
Definition htable.f90:277
subroutine htable_iter_data(this, data)
Return the data at the current iterator position.
Definition htable.f90:718
pure integer function htable_size(this)
Return total size of htable.
Definition htable.f90:318
subroutine htable_get_data(this, idx, data)
Return data at idx in value.
Definition htable.f90:556
integer function htable_r8_get(this, key, data)
Retrive a double precision float with key key from the hash table.
Definition htable.f90:1046
pure integer function htable_i8_hash(this, k, c)
Hash function for an integer*8 based hash table.
Definition htable.f90:925
subroutine htable_i4t4_remove(this, key)
Remove an integer 4-tuple with key key from the hash table.
Definition htable.f90:1461
integer function htable_get(this, key, data)
Retrieve data associated with key into the hash table.
Definition htable.f90:437
integer function htable_i8_get(this, key, data)
Retrive an integer*8 with key key from the hash table.
Definition htable.f90:914
integer function htable_pt_get(this, key, data)
Retrive a point with key key from the hash table.
Definition htable.f90:1153
subroutine htable_remove(this, key)
Remove a key from the hash table.
Definition htable.f90:470
subroutine htable_set_data(this, idx, data)
Set data at idx to value.
Definition htable.f90:510
real(kind=dp) function, pointer htable_iter_r8_key(this)
Return the current key of the double precision based hash table iterator.
Definition htable.f90:1111
subroutine htable_iter_pt_init(this, t)
Initialize a point based hash table iterator.
Definition htable.f90:1212
integer function htable_i4_get(this, key, data)
Retrive an integer with key key from the hash table.
Definition htable.f90:792
type(h_cptr_t) function, pointer htable_iter_cptr_value(this)
Return the current value of C pointer based hash table iterator.
Definition htable.f90:1604
type(tuple_i4_t) function, pointer htable_iter_i4t2_value(this)
Return the current value of integer based 2-tuple hash table iterator.
Definition htable.f90:1357
logical function htable_iter_next(this)
Advance the iterator to the next valid table entry.
Definition htable.f90:690
integer function htable_cptr_get(this, key, data)
Retrive a C pointer with key key from the hash table.
Definition htable.f90:1550
subroutine htable_i8_set(this, key, data)
Insert an integer*8 into the hash table.
Definition htable.f90:904
subroutine htable_r8_remove(this, key)
Remove a double precision key key from the hash table.
Definition htable.f90:1071
subroutine htable_iter_i4t2_free(this)
Destroy an integer 2-tuple based hash table iterator.
Definition htable.f90:1350
subroutine htable_r8_set(this, key, data)
Insert a double precision key (with data) into the hash table.
Definition htable.f90:1036
type(point_t) function, pointer htable_iter_pt_value(this)
Return the current value of the point based hash table iterator.
Definition htable.f90:1228
integer function htable_i4t4_get(this, key, data)
Retrive an integer 4-tuple with key key from the hash table.
Definition htable.f90:1413
subroutine htable_i4t2_set(this, key, data)
Insert an integer 2-tuple into the hash table.
Definition htable.f90:1274
pure integer function htable_num_entries(this)
Return number of entries in the table.
Definition htable.f90:311
type(tuple4_i4_t) function, pointer htable_iter_i4t4_key(this)
Return the current key of integer based 4-tuple hash table iterator.
Definition htable.f90:1500
recursive subroutine htable_set(this, key, data)
Insert tuple (key, value) into the hash table.
Definition htable.f90:326
pure logical function htable_eq_key(this, idx, key)
Compare key at idx to key.
Definition htable.f90:600
subroutine htable_i4t2_remove(this, key)
Remove an integer 2-tuple with key key from the hash table.
Definition htable.f90:1332
subroutine htable_set_key(this, idx, key)
Set key at idx to key.
Definition htable.f90:644
subroutine htable_iter_i8_init(this, t)
Initialize an integer*8 based hash table iterator.
Definition htable.f90:965
pure integer function htable_i4t4_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
Definition htable.f90:1424
pure integer function htable_pt_hash(this, k, c)
Hash function for a point based hash table.
Definition htable.f90:1164
integer function, pointer htable_iter_i4_key(this)
Return the current key of the integer based hash table iterator.
Definition htable.f90:872
subroutine htable_iter_i4_init(this, t)
Initialize an integer based hash table iterator.
Definition htable.f90:842
subroutine htable_init(this, size, key, data)
Initialize a hash table of type data.
Definition htable.f90:243
subroutine htable_i4t2_init(this, size, data)
Initialize an integer 2-tuple hash table.
Definition htable.f90:1259
subroutine htable_cptr_set(this, key, data)
Insert a C pointer into the hash table.
Definition htable.f90:1540
subroutine htable_iter_i4t4_free(this)
Destroy an integer 4-tuple based hash table iterator.
Definition htable.f90:1479
subroutine htable_i4_remove(this, key)
Remove an integer with key key from the hash table.
Definition htable.f90:833
subroutine htable_iter_cptr_init(this, t)
Initialize a C pointer based hash table iterator.
Definition htable.f90:1588
integer(kind=i8) function, pointer htable_iter_i8_value(this)
Return the current value of the integer*8 based hash table iterator.
Definition htable.f90:981
integer function htable_i4t2_get(this, key, data)
Retrive an integer 2-tuple with key key from the hash table.
Definition htable.f90:1284
subroutine htable_iter_i4t4_init(this, t)
Initialize an integer 4-tuple based hash table iterator.
Definition htable.f90:1470
subroutine htable_i8_remove(this, key)
Remove an integer*8 with key key from the hash table.
Definition htable.f90:956
subroutine htable_i4_init(this, size, data)
Initialize an integer based hash table.
Definition htable.f90:767
pure integer function htable_cptr_hash(this, k, c)
Hash function for an integer 4-tuple hash table.
Definition htable.f90:1561
subroutine htable_pt_set(this, key, data)
Insert a point key (with data) into the hash table.
Definition htable.f90:1143
subroutine htable_iter_reset(this)
Reset an iterator.
Definition htable.f90:709
subroutine htable_iter_i4_free(this)
Destroy an integer based hash table iterator.
Definition htable.f90:851
type(h_cptr_t) function, pointer htable_iter_cptr_key(this)
Return the current key of a C pointer based hash table iterator.
Definition htable.f90:1620
subroutine htable_iter_r8_free(this)
Destroy a double precision based hash table iterator.
Definition htable.f90:1090
pure integer function htable_i4t2_hash(this, k, c)
Hash function for an integer 2-tuple hash table.
Definition htable.f90:1295
subroutine htable_iter_i4t2_init(this, t)
Initialize an integer 2-tuple based hash table iterator.
Definition htable.f90:1341
real(kind=dp) function, pointer htable_iter_r8_value(this)
Return the current value of the double precision based hash table iterator.
Definition htable.f90:1097
Definition math.f90:60
real(kind=rp), parameter, public neko_m_ln2
Definition math.f90:72
integer, parameter, public i8
Definition num_types.f90:7
integer, parameter, public i4
Definition num_types.f90:6
integer, parameter, public dp
Definition num_types.f90:9
Implements a point.
Definition point.f90:35
Implements a n-tuple.
Definition tuple.f90:34
Utilities.
Definition utils.f90:35
Hash table entry, tuple (key, data)
Definition htable.f90:47
C pointer based hash table.
Definition htable.f90:146
Integer based hash table.
Definition htable.f90:86
Integer 2-tuple based hash table.
Definition htable.f90:126
Integer 4-tuple based hash table.
Definition htable.f90:136
Integer*8 based hash table.
Definition htable.f90:96
Iterator for a C pointer based hash table.
Definition htable.f90:224
Iterator for an integer based hash table.
Definition htable.f90:170
Iterator for an integer based 2-tuple hash table.
Definition htable.f90:206
Iterator for an integer based 4-tuple hash table.
Definition htable.f90:215
Iterator for an integer*8 based hash table.
Definition htable.f90:179
Iterator for a point based hash table.
Definition htable.f90:197
Iterator for a double precision based hash table.
Definition htable.f90:188
Base type for a hash table iterator.
Definition htable.f90:160
Point based hash table.
Definition htable.f90:116
Double precision based hash table.
Definition htable.f90:106
Base type for a hash table.
Definition htable.f90:57
A point in with coordinates .
Definition point.f90:43
Integer based 4-tuple.
Definition tuple.f90:69
Integer based 2-tuple.
Definition tuple.f90:51
Base type for an n-tuple.
Definition tuple.f90:41