util.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2019, The University of Memphis
4  *
5  * This file is part of PSync.
6  * See AUTHORS.md for complete list of PSync authors and contributors.
7  *
8  * PSync is free software: you can redistribute it and/or modify it under the terms
9  * of the GNU Lesser General Public License as published by the Free Software Foundation,
10  * either version 3 of the License, or (at your option) any later version.
11  *
12  * PSync is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  * PURPOSE. See the GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License along with
17  * PSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * murmurHash3 was written by Austin Appleby, and is placed in the public
20  * domain. The author hereby disclaims copyright to this source code.
21  * https://github.com/aappleby/smhasher/blob/master/src/murmurHash3.cpp
22  **/
23 
24 #include "PSync/detail/util.hpp"
25 
26 #include <ndn-cxx/util/backports.hpp>
27 
28 namespace psync {
29 
30 static uint32_t
31 ROTL32 ( uint32_t x, int8_t r )
32 {
33  return (x << r) | (x >> (32 - r));
34 }
35 
36 uint32_t
37 murmurHash3(uint32_t nHashSeed, const std::vector<unsigned char>& vDataToHash)
38 {
39  uint32_t h1 = nHashSeed;
40  const uint32_t c1 = 0xcc9e2d51;
41  const uint32_t c2 = 0x1b873593;
42 
43  const size_t nblocks = vDataToHash.size() / 4;
44 
45  //----------
46  // body
47  const uint32_t * blocks = (const uint32_t *)(&vDataToHash[0] + nblocks*4);
48 
49  for (size_t i = -nblocks; i; i++) {
50  uint32_t k1 = blocks[i];
51 
52  k1 *= c1;
53  k1 = ROTL32(k1,15);
54  k1 *= c2;
55 
56  h1 ^= k1;
57  h1 = ROTL32(h1,13);
58  h1 = h1*5+0xe6546b64;
59  }
60 
61  //----------
62  // tail
63  const uint8_t * tail = (const uint8_t*)(&vDataToHash[0] + nblocks*4);
64 
65  uint32_t k1 = 0;
66 
67  switch (vDataToHash.size() & 3) {
68  case 3:
69  k1 ^= tail[2] << 16;
70  NDN_CXX_FALLTHROUGH;
71 
72  case 2:
73  k1 ^= tail[1] << 8;
74  NDN_CXX_FALLTHROUGH;
75 
76  case 1:
77  k1 ^= tail[0];
78  k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
79  }
80 
81  //----------
82  // finalization
83  h1 ^= vDataToHash.size();
84  h1 ^= h1 >> 16;
85  h1 *= 0x85ebca6b;
86  h1 ^= h1 >> 13;
87  h1 *= 0xc2b2ae35;
88  h1 ^= h1 >> 16;
89 
90  return h1;
91 }
92 
93 uint32_t
94 murmurHash3(uint32_t nHashSeed, const std::string& str)
95 {
96  return murmurHash3(nHashSeed, std::vector<unsigned char>(str.begin(), str.end()));
97 }
98 
99 uint32_t
100 murmurHash3(uint32_t nHashSeed, uint32_t value)
101 {
102  return murmurHash3(nHashSeed,
103  std::vector<unsigned char>((unsigned char*)&value,
104  (unsigned char*)&value + sizeof(uint32_t)));
105 }
106 
107 } // namespace psync
uint32_t murmurHash3(uint32_t nHashSeed, const std::vector< unsigned char > &vDataToHash)
Definition: util.cpp:37
static uint32_t ROTL32(uint32_t x, int8_t r)
Definition: util.cpp:31