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