• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkChecksum.h"
9 
Murmur3(const void * data,size_t bytes,uint32_t seed)10 uint32_t SkChecksum::Murmur3(const void* data, size_t bytes, uint32_t seed) {
11     // Use may_alias to remind the compiler we're intentionally violating strict aliasing,
12     // and so not to apply strict-aliasing-based optimizations.
13     typedef uint32_t SK_ATTRIBUTE(may_alias) aliased_uint32_t;
14     typedef uint8_t SK_ATTRIBUTE(may_alias) aliased_uint8_t;
15 
16     // Handle 4 bytes at a time while possible.
17     const aliased_uint32_t* safe_data = (const aliased_uint32_t*)data;
18     const size_t words = bytes/4;
19     uint32_t hash = seed;
20     for (size_t i = 0; i < words; i++) {
21         uint32_t k = safe_data[i];
22         k *= 0xcc9e2d51;
23         k = (k << 15) | (k >> 17);
24         k *= 0x1b873593;
25 
26         hash ^= k;
27         hash = (hash << 13) | (hash >> 19);
28         hash *= 5;
29         hash += 0xe6546b64;
30     }
31 
32     // Handle last 0-3 bytes.
33     const aliased_uint8_t* safe_tail = (const uint8_t*)(safe_data + words);
34     uint32_t k = 0;
35     switch (bytes & 3) {
36         case 3: k ^= safe_tail[2] << 16;
37         case 2: k ^= safe_tail[1] <<  8;
38         case 1: k ^= safe_tail[0] <<  0;
39                 k *= 0xcc9e2d51;
40                 k = (k << 15) | (k >> 17);
41                 k *= 0x1b873593;
42                 hash ^= k;
43     }
44 
45     hash ^= bytes;
46     return SkChecksum::Mix(hash);
47 }
48