Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
hash-fct.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
178# ifndef HASH_FCT_H
179# define HASH_FCT_H
180
181# include <cstdint>
182# include <cstdlib>
183# include <cstring>
184# include <string>
185# include <primes.H>
186
187namespace Aleph
188{
189
205 extern const unsigned Default_Hash_Seed;
206
220 inline size_t add_hash(const void * key, const size_t len) noexcept
221 {
222 const auto *p = static_cast<const unsigned char *>(key);
223 size_t h = 0;
224
225 for (size_t i = 0; i < len; i++)
226 h += p[i];
227
228 return h;
229 }
230
241 inline size_t xor_hash(const void * key, const size_t len) noexcept
242 {
243 const auto *p = static_cast<const unsigned char *>(key);
244 size_t h = 0;
245
246 for (size_t i = 0; i < len; i++)
247 h ^= p[i];
248
249 return h;
250 }
251
252
268 inline size_t rot_hash(const void * key, const size_t len) noexcept
269 {
270 const auto *p = static_cast<const unsigned char *>(key);
271 size_t h = 0;
272
273 for (size_t i = 0; i < len; i++)
274 h = (h << 4) ^(h >> 28) ^ p[i];
275
276 return h;
277 }
278
279
308 inline size_t djb_hash(const void * key, const size_t len) noexcept
309 {
310 const auto *p = static_cast<const unsigned char *>(key);
311 size_t h = 0;
312
313 for (size_t i = 0; i < len; i++)
314 h = 33 * h ^ p[i];
315
316 return h;
317 }
318
333 inline size_t sax_hash(const void * key, const size_t len) noexcept
334 {
335 const auto *p = static_cast<const unsigned char *>(key);
336 size_t h = 0;
337
338 for (size_t i = 0; i < len; i++)
339 h ^= (h << 5) +(h >> 2) + p[i];
340
341 return h;
342 }
343
371 inline size_t fnv_hash(const void * key, const size_t len) noexcept
372 {
373 const auto *p = static_cast<const unsigned char *>(key);
374 size_t h = 2166136261;
375
376 for (size_t i = 0; i < len; i++)
377 h = (h * 16777619) ^ p[i];
378
379 return h;
380 }
381
382
404 inline size_t oat_hash(const void * key, const size_t len) noexcept
405 {
406 const auto *p = static_cast<const unsigned char *>(key);
407 size_t h = 0;
408
409 for (size_t i = 0; i < len; i++)
410 {
411 h += p[i];
412 h += (h << 10);
413 h ^= (h >> 6);
414 }
415
416 h += (h << 3);
417 h ^= (h >> 11);
418 h += (h << 15);
419
420 return h;
421 }
422
423 extern size_t jsw_hash(const void * key, size_t len);
424
425
439 inline size_t elf_hash(const void * key, const size_t len) noexcept
440 {
441 const auto *p = static_cast<const unsigned char *>(key);
442 size_t h = 0;
443
444 for (size_t i = 0; i < len; i++)
445 {
446 h = (h << 4) + p[i];
447 size_t g = h & 0xf0000000L;
448
449 if(g != 0)
450 h ^= g >> 24;
451
452 h &= ~g;
453 }
454
455 return h;
456 }
457
458
459#define hashsize(n)(1U << (n))
460#define hashmask(n)(hashsize(n) - 1)
461
462 inline void mix(size_t & a, size_t & b, size_t & c) noexcept
463 {
464 a -= b; a -= c; a ^=(c >> 13);
465 b -= c; b -= a; b ^=(a << 8);
466 c -= a; c -= b; c ^=(b >> 13);
467 a -= b; a -= c; a ^=(c >> 12);
468 b -= c; b -= a; b ^=(a << 16);
469 c -= a; c -= b; c ^=(b >> 5);
470 a -= b; a -= c; a ^=(c >> 3);
471 b -= c; b -= a; b ^=(a << 10);
472 c -= a; c -= b; c ^=(b >> 15);
473 }
474
475
488 inline size_t jen_hash(const void * key, const size_t length,
489 const unsigned initval = Default_Hash_Seed) noexcept
490 {
491 const auto * k = static_cast<const unsigned char *>(key);
492 size_t b;
493 size_t c = initval;
494 size_t len = length;
495
496 size_t a = b = 0x9e3779b9;
497
498 while (len >= 12)
499 {
500 a += (k[0] +(static_cast<size_t>(k[1]) << 8) + (static_cast<size_t>(k[2]) << 16) +
501 (static_cast<size_t>(k[3]) << 24));
502 b += (k[4] +(static_cast<size_t>(k[5]) << 8) + (static_cast<size_t>(k[6]) << 16) +
503 (static_cast<size_t>(k[7]) << 24));
504 c += (k[8] +(static_cast<size_t>(k[9]) << 8) + (static_cast<size_t>(k[10]) << 16) +
505 (static_cast<size_t>(k[11]) << 24));
506
507 mix(a, b, c);
508
509 k += 12;
510 len -= 12;
511 }
512
513 c += length;
514
515 switch(len)
516 {
517 case 11: c += (static_cast<size_t>(k[10]) << 24); [[fallthrough]];
518 case 10: c += (static_cast<size_t>(k[9]) << 16); [[fallthrough]];
519 case 9 : c += (static_cast<size_t>(k[8]) << 8); [[fallthrough]];
520 /* First byte of c reserved for length */
521 case 8 : b += (static_cast<size_t>(k[7]) << 24); [[fallthrough]];
522 case 7 : b += (static_cast<size_t>(k[6]) << 16); [[fallthrough]];
523 case 6 : b += (static_cast<size_t>(k[5]) << 8); [[fallthrough]];
524 case 5 : b += k[4]; [[fallthrough]];
525 case 4 : a += (static_cast<size_t>(k[3]) << 24); [[fallthrough]];
526 case 3 : a += (static_cast<size_t>(k[2]) << 16); [[fallthrough]];
527 case 2 : a += (static_cast<size_t>(k[1]) << 8); [[fallthrough]];
528 case 1 : a += k[0]; break;
529 default: break;
530 }
531
532 mix(a, b, c);
533
534 return c;
535 }
536
537 /* The following three functions were taken from
538
539 https://github.com/PeterScott/murmur3
540
541 They are a port of MurmurHash created by Austin Appleby and written
542 by Peter Scott
543
544 See at
545
546 http://en.wikipedia.org/wiki/MurmurHash
547
548 For more details
549 */
550
551 void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out);
552
553 void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out);
554
555 void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out);
556
558 {
559 std::uint32_t a[4];
560 };
561
562 template <typename Key> inline
563 size_t murmur3hash(const Key & key, unsigned long seed)
564 {
565# ifdef __x86_64__
567 MurmurHash3_x64_128(&key, sizeof(key), seed, &buf);
568# else
569 size_t buf;
570 MurmurHash3_x86_32(&key, sizeof(key), seed, &buf);
571# endif
572
573 size_t ret;
574 memcpy(&ret, &buf, sizeof(ret));
575
576 return ret;
577 }
578
579
580 inline size_t murmur3hash(const char * key, const unsigned long seed)
581 {
582 const size_t len = strlen(key);
583# ifdef __x86_64__
585 MurmurHash3_x64_128(key, len, seed, &buf);
586# else
587 size_t buf;
588 MurmurHash3_x86_32(key, len, seed, &buf);
589# endif
590
591 size_t ret;
592 memcpy(&ret, &buf, sizeof(ret));
593
594 return ret;
595 }
596
597 template <> inline
598 size_t murmur3hash(const std::string & key, const unsigned long seed)
599 {
600# ifdef __x86_64__
602 MurmurHash3_x64_128(key.c_str(), key.size(), seed, &buf);
603# else
604 size_t buf;
605 MurmurHash3_x86_32(key.c_str(), key.size(), seed, &buf);
606# endif
607
608 size_t ret;
609 memcpy(&ret, &buf, sizeof(ret));
610
611 return ret;
612 }
613
614
615 /* Paul Hsieh superfast hash function.
616
617 Taken from
618
619 http://www.azillionmonkeys.com/qed/hash.html
620 */
621
622#undef get16bits
623#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
624 || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
625#define get16bits(d) (*((const uint16_t *) (d)))
626#endif
627
628#if !defined (get16bits)
629#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
630 +(uint32_t)(((const uint8_t *)(d))[0]) )
631#endif
632
638 inline size_t SuperFastHash(const void * key, size_t len) noexcept
639 {
640 const auto * data = static_cast<const unsigned char *>(key);
641 size_t hash = len;
642
643 if (len <= 0 || data == nullptr)
644 return 0;
645
646 const int rem = len & 3;
647 len >>= 2;
648
649 /* Main loop */
650 for (;len > 0; --len)
651 {
652 hash += get16bits (data);
653 const size_t tmp = (get16bits(data+2) << 11) ^ hash;
654 hash = (hash << 16) ^ tmp;
655 data += 2*sizeof (uint16_t);
656 hash += hash >> 11;
657 }
658
659 /* Handle end cases */
660 switch (rem)
661 {
662 case 3:
663 hash += get16bits (data);
664 hash ^= hash << 16;
665 hash ^= static_cast<signed char>(data[sizeof(uint16_t)]) << 18;
666 hash += hash >> 11;
667 break;
668 case 2:
669 hash += get16bits (data);
670 hash ^= hash << 11;
671 hash += hash >> 17;
672 break;
673 case 1:
674 hash += static_cast<signed char>(*data);
675 hash ^= hash << 10;
676 hash += hash >> 1;
677 break;
678 default:
679 break;
680 }
681
682 /* Force "avalanching" of final 127 bits */
683 hash ^= hash << 3;
684 hash += hash >> 5;
685 hash ^= hash << 4;
686 hash += hash >> 17;
687 hash ^= hash << 25;
688 hash += hash >> 6;
689
690 return hash;
691 }
692
693 template <typename Key> inline
694 size_t add_hash(const Key & key) noexcept
695 {
696 return add_hash(&key, sizeof(key));
697 }
698
699 template <typename Key> inline
700 size_t xor_hash(const Key & key) noexcept
701 {
702 return xor_hash(&key, sizeof(key));
703 }
704
705 template <typename Key>
706 size_t rot_hash(const Key & key) noexcept
707 {
708 return rot_hash(&key, sizeof(key));
709 }
710
711 template <typename Key>
712 size_t djb_hash(const Key & key) noexcept
713 {
714 return djb_hash(&key, sizeof(key));
715 }
716
717 template <typename Key>
718 size_t sax_hash(const Key & key) noexcept
719 {
720 return sax_hash(&key, sizeof(key));
721 }
722
723 template <typename Key>
724 size_t fnv_hash(const Key & key) noexcept
725 {
726 return fnv_hash(&key, sizeof(key));
727 }
728
729 template <typename Key>
730 size_t oat_hash(const Key & key) noexcept
731 {
732 return oat_hash(&key, sizeof(key));
733 }
734
737 template <typename Key>
738 size_t jsw_hash(const Key & key)
739 {
740 return jsw_hash(&key, sizeof(key));
741 }
742
743 template <typename Key>
744 size_t elf_hash(const Key & key) noexcept
745 {
746 return elf_hash(&key, sizeof(key));
747 }
748
749 template <typename Key>
750 size_t jen_hash(const Key & key, const unsigned initval) noexcept
751 {
752 return jen_hash(&key, sizeof(key), initval);
753 }
754
755 template <typename Key>
756 size_t SuperFastHash(const Key & key) noexcept
757 {
758 return SuperFastHash(&key, sizeof(key));
759 }
760
761 inline size_t add_hash(const char * key) noexcept
762 {
763 auto p = reinterpret_cast<const unsigned char *>(key);
764 size_t h = 0;
765
766 while (*p)
767 h += *p++;
768
769 return h;
770 }
771
772 inline size_t xor_hash(const char * key) noexcept
773 {
774 auto p = reinterpret_cast<const unsigned char *>(key);
775 size_t h = 0;
776
777 while (*p)
778 h ^= *p++;
779
780 return h;
781 }
782
783 inline size_t rot_hash(const char * key) noexcept
784 {
785 auto p = reinterpret_cast<const unsigned char *>(key);
786 size_t h = 0;
787
788 while (*p)
789 h = (h << 4) ^(h >> 28) ^ *p++;
790
791 return h;
792 }
793
794 inline size_t djb_hash(const char * key) noexcept
795 {
796 auto p = reinterpret_cast<const unsigned char *>(key);
797 size_t h = 0;
798
799 while (*p)
800 h = 33 * h ^ *p++;
801
802 return h;
803 }
804
805 inline size_t sax_hash(const char * key) noexcept
806 {
807 auto p = reinterpret_cast<const unsigned char *>(key);
808 size_t h = 0;
809
810 while (*p)
811 h ^= (h << 5) +(h >> 2) + *p++;
812
813 return h;
814 }
815
816 inline size_t fnv_hash(const char * key) noexcept
817 {
818 auto p = reinterpret_cast<const unsigned char *>(key);
819 size_t h = 2166136261;
820
821 while (*p)
822 h = (h * 16777619) ^ *p++;
823
824 return h;
825 }
826
827 inline size_t oat_hash(const char * key) noexcept
828 {
829 auto p = reinterpret_cast<const unsigned char *>(key);
830 size_t h = 0;
831
832 while (*p)
833 {
834 h += *p++;
835 h += (h << 10);
836 h ^= (h >> 6);
837 }
838
839 h += (h << 3);
840 h ^= (h >> 11);
841 h += (h << 15);
842
843 return h;
844 }
845
846 extern size_t jsw_hash(const char * key);
847
848 inline size_t elf_hash(const char * key) noexcept
849 {
850 auto p = reinterpret_cast<const unsigned char *>(key);
851 size_t h = 0;
852
853 while (*p)
854 {
855 h =(h << 4) + *p++;
856 size_t g = h & 0xf0000000L;
857
858 if(g != 0)
859 h ^= g >> 24;
860
861 h &= ~g;
862 }
863
864 return h;
865 }
866
867 inline size_t SuperFastHash(const char * key) noexcept
868 {
869 return SuperFastHash(key, strlen(key));
870 }
871
872 template <>
873 inline size_t add_hash(const std::string & key) noexcept
874 {
875 return add_hash(key.c_str());
876 }
877
878 inline size_t xor_hash(const std::string & key) noexcept
879 {
880 return xor_hash(key.c_str());
881 }
882
883 inline size_t rot_hash(const std::string & key) noexcept
884 {
885 return rot_hash(key.c_str());
886 }
887
888 inline size_t djb_hash(const std::string & key) noexcept
889 {
890 return djb_hash(key.c_str());
891 }
892
893 inline size_t sax_hash(const std::string & key) noexcept
894 {
895 return sax_hash(key.c_str());
896 }
897
898 inline size_t fnv_hash(const std::string & key) noexcept
899 {
900 return fnv_hash(key.c_str());
901 }
902
903 inline size_t oat_hash(const std::string & key) noexcept
904 {
905 return oat_hash(key.c_str());
906 }
907
910 inline size_t jsw_hash(const std::string & key)
911 {
912 return jsw_hash(key.c_str());
913 }
914
915 inline size_t elf_hash(const std::string & key) noexcept
916 {
917 return elf_hash(key.c_str());
918 }
919
920 inline size_t jen_hash(const std::string & key, unsigned initval) noexcept
921 {
922 return jen_hash(key.c_str(), key.size(), initval);
923 }
924
925 inline size_t SuperFastHash(const std::string & key) noexcept
926 {
927 return SuperFastHash(key.c_str(), key.size());
928 }
929
930 template <typename Key> inline
931 size_t dft_hash_fct(const Key & key) noexcept
932 {
933 return SuperFastHash(key);
934 }
935
936 template <typename Key> inline
937 size_t snd_hash_fct(const Key & key) noexcept
938 {
939 return murmur3hash(key, 52679987);
940 }
941
942 template <typename Key> inline
943 size_t dft_hash_fct(const Key & key, unsigned long seed) noexcept
944 {
945 return murmur3hash(key, seed);
946 }
947
948 template<typename Key, typename Data, typename Fct>
949 inline size_t map_hash_fct(Fct fct, const std::pair<Key, Data> & p) noexcept
950 {
951 return fct(p.first);
952 }
953
954 template <typename K1, typename K2> inline
955 size_t pair_dft_hash_fct(const std::pair<K1, K2> & p) noexcept
956 {
957 return dft_hash_fct(p.first) + dft_hash_fct(p.second);
958 }
959
960 template <typename K1, typename K2> inline
961 size_t pair_snd_hash_fct(const std::pair<K1, K2> & p) noexcept
962 {
963 return dft_hash_fct(p.first) + snd_hash_fct(p.second);
964 }
965
966} // end namespace Aleph
967
968
969# endif // HASH_FCT_H
long double h
Definition btreepic.C:154
#define get16bits(d)
Definition hash-fct.H:629
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
size_t map_hash_fct(Fct fct, const std::pair< Key, Data > &p) noexcept
Definition hash-fct.H:949
size_t sax_hash(const void *key, const size_t len) noexcept
Shift-Add-XOR hash.
Definition hash-fct.H:333
void MurmurHash3_x86_32(const void *key, int len, uint32_t seed, void *out)
Definition hash-fct.C:185
void mix(size_t &a, size_t &b, size_t &c) noexcept
Definition hash-fct.H:462
size_t snd_hash_fct(const Key &key) noexcept
Definition hash-fct.H:937
void MurmurHash3_x64_128(const void *key, const int len, const uint32_t seed, void *out)
Definition hash-fct.C:348
size_t add_hash(const void *key, const size_t len) noexcept
Additive hash.
Definition hash-fct.H:220
size_t pair_dft_hash_fct(const std::pair< K1, K2 > &p) noexcept
Definition hash-fct.H:955
size_t jsw_hash(const void *key, size_t len)
JSW hash (Julienne Walker)
Definition hash-fct.C:83
size_t murmur3hash(const Key &key, unsigned long seed)
Definition hash-fct.H:563
size_t djb_hash(const void *key, const size_t len) noexcept
Modified Bernstein hash.
Definition hash-fct.H:308
size_t SuperFastHash(const void *key, size_t len) noexcept
Paul Hsieh super fast hash function.
Definition hash-fct.H:638
size_t jen_hash(const void *key, const size_t length, const unsigned initval=Default_Hash_Seed) noexcept
Jenkins hash.
Definition hash-fct.H:488
size_t dft_hash_fct(const Key &key) noexcept
Definition hash-fct.H:931
size_t pair_snd_hash_fct(const std::pair< K1, K2 > &p) noexcept
Definition hash-fct.H:961
void MurmurHash3_x86_128(const void *key, const int len, uint32_t seed, void *out)
Definition hash-fct.C:242
const unsigned Default_Hash_Seed
Hash functions (implementaciones concretas).
Definition hash-fct.C:43
size_t xor_hash(const void *key, const size_t len) noexcept
XOR hash.
Definition hash-fct.H:241
size_t fnv_hash(const void *key, const size_t len) noexcept
Fowler-Noll-Vo (FNV-1) hash function.
Definition hash-fct.H:371
size_t rot_hash(const void *key, const size_t len) noexcept
Rotating hash.
Definition hash-fct.H:268
size_t elf_hash(const void *key, const size_t len) noexcept
ELF hash.
Definition hash-fct.H:439
size_t oat_hash(const void *key, const size_t len) noexcept
One-at-a-Time hash by Bob Jenkins.
Definition hash-fct.H:404
DynList< T > maps(const C &c, Op op)
Classic map operation.
Prime number utilities for hash tables and mathematical operations.
std::uint32_t a[4]
Definition hash-fct.H:559