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