1 | /* |
2 | * Copyright 2012 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 | #ifndef SkChecksum_DEFINED |
9 | #define SkChecksum_DEFINED |
10 | |
11 | #include "include/core/SkString.h" |
12 | #include "include/core/SkTypes.h" |
13 | #include "include/private/SkNoncopyable.h" |
14 | #include "include/private/SkTLogic.h" |
15 | |
16 | // #include "src/core/SkOpts.h" |
17 | // It's sort of pesky to be able to include SkOpts.h here, so we'll just re-declare what we need. |
18 | namespace SkOpts { |
19 | extern uint32_t (*hash_fn)(const void*, size_t, uint32_t); |
20 | } |
21 | |
22 | class SkChecksum : SkNoncopyable { |
23 | public: |
24 | /** |
25 | * uint32_t -> uint32_t hash, useful for when you're about to trucate this hash but you |
26 | * suspect its low bits aren't well mixed. |
27 | * |
28 | * This is the Murmur3 finalizer. |
29 | */ |
30 | static uint32_t Mix(uint32_t hash) { |
31 | hash ^= hash >> 16; |
32 | hash *= 0x85ebca6b; |
33 | hash ^= hash >> 13; |
34 | hash *= 0xc2b2ae35; |
35 | hash ^= hash >> 16; |
36 | return hash; |
37 | } |
38 | |
39 | /** |
40 | * uint32_t -> uint32_t hash, useful for when you're about to trucate this hash but you |
41 | * suspect its low bits aren't well mixed. |
42 | * |
43 | * This version is 2-lines cheaper than Mix, but seems to be sufficient for the font cache. |
44 | */ |
45 | static uint32_t CheapMix(uint32_t hash) { |
46 | hash ^= hash >> 16; |
47 | hash *= 0x85ebca6b; |
48 | hash ^= hash >> 16; |
49 | return hash; |
50 | } |
51 | }; |
52 | |
53 | // SkGoodHash should usually be your first choice in hashing data. |
54 | // It should be both reasonably fast and high quality. |
55 | struct SkGoodHash { |
56 | template <typename K> |
57 | SK_WHEN(sizeof(K) == 4, uint32_t) operator()(const K& k) const { |
58 | return SkChecksum::Mix(*(const uint32_t*)&k); |
59 | } |
60 | |
61 | template <typename K> |
62 | SK_WHEN(sizeof(K) != 4, uint32_t) operator()(const K& k) const { |
63 | return SkOpts::hash_fn(&k, sizeof(K), 0); |
64 | } |
65 | |
66 | uint32_t operator()(const SkString& k) const { |
67 | return SkOpts::hash_fn(k.c_str(), k.size(), 0); |
68 | } |
69 | }; |
70 | |
71 | #endif |
72 | |