Home | History | Annotate | Download | only in core
      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 
     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