hashfunc.hh 2.97 KB
Newer Older
1
// -*- coding: utf-8 -*-
2
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
3
// de l'Epita (LRDE)
4
// Copyright (C) 2004, 2005  Laboratoire d'Informatique de Paris 6 (LIP6),
5
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
6
7
8
9
10
11
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
12
// the Free Software Foundation; either version 3 of the License, or
13
14
15
16
17
18
19
20
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
22

23
24
25
#pragma once

#include <cstddef>
26
#include <cstdint>
27

28
29
namespace spot
{
30
  /// \defgroup hash_funcs Hashing functions
31
  /// \ingroup misc_tools
32
33

  /// \ingroup hash_funcs
34
35
  /// @{

36
37
38
  /// \brief Thomas Wang's 32 bit hash function.
  ///
  /// Hash an integer amongst the integers.
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
39
  /// http://web.archive.org/web/2011/concentric.net/~Ttwang/tech/inthash.htm
40
41
42
43
44
45
46
47
48
49
50
51
  inline size_t
  wang32_hash(size_t key)
  {
    // We assume that size_t has at least 32bits.
    key += ~(key << 15);
    key ^=  (key >> 10);
    key +=  (key << 3);
    key ^=  (key >> 6);
    key += ~(key << 11);
    key ^=  (key >> 16);
    return key;
  }
52
53
54
55
56
57

  /// \brief Knuth's Multiplicative hash function.
  ///
  /// This function is suitable for hashing values whose
  /// high order bits do not vary much (ex. addresses of
  /// memory objects).  Prefer spot::wang32_hash() otherwise.
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
58
  /// http://web.archive.org/web/2011/concentric.net/~Ttwang/tech/addrhash.htm
59
60
61
62
63
64
65
  inline size_t
  knuth32_hash(size_t key)
  {
    // 2654435761 is the golden ratio of 2^32.  The right shift of 3
    // bits assumes that all objects are aligned on a 8 byte boundary.
    return (key >> 3) * 2654435761U;
  }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

  /// Struct for Fowler-Noll-Vo parameters
  template<class T>
  struct fnv
  {};

  /// Fowler-Noll-Vo hash parameters for 32 bits
  template<>
  struct fnv<uint32_t>
  {
    static constexpr uint32_t init = 2166136261UL;
    static constexpr uint32_t prime = 16777619UL;
  };

  /// Fowler-Noll-Vo hash parameters for 64 bits
  template<>
  struct fnv<uint64_t>
  {
    static constexpr uint64_t init = 14695981039346656037UL;
    static constexpr uint64_t prime = 1099511628211UL;
  };

  /// \brief Fowler-Noll-Vo hash function
  ///
  /// This function is a non-cryptographic fast hash function.
  /// The magic constants depend on the size of a size_t.
  template<class It>
  size_t
  fnv_hash(It begin, It end)
  {
    size_t res = fnv<size_t>::init;
    for (; begin != end; ++begin)
      {
        res ^= *begin;
        res *= fnv<size_t>::prime;
      }
    return res;
  }

105
  /// @}
106
}