1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SkChecksum_DEFINED 9cb93a386Sopenharmony_ci#define SkChecksum_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/core/SkString.h" 12cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 13cb93a386Sopenharmony_ci#include "include/private/SkNoncopyable.h" 14cb93a386Sopenharmony_ci#include "include/private/SkOpts_spi.h" 15cb93a386Sopenharmony_ci#include "include/private/SkTLogic.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciclass SkChecksum : SkNoncopyable { 18cb93a386Sopenharmony_cipublic: 19cb93a386Sopenharmony_ci /** 20cb93a386Sopenharmony_ci * uint32_t -> uint32_t hash, useful for when you're about to trucate this hash but you 21cb93a386Sopenharmony_ci * suspect its low bits aren't well mixed. 22cb93a386Sopenharmony_ci * 23cb93a386Sopenharmony_ci * This is the Murmur3 finalizer. 24cb93a386Sopenharmony_ci */ 25cb93a386Sopenharmony_ci static uint32_t Mix(uint32_t hash) { 26cb93a386Sopenharmony_ci hash ^= hash >> 16; 27cb93a386Sopenharmony_ci hash *= 0x85ebca6b; 28cb93a386Sopenharmony_ci hash ^= hash >> 13; 29cb93a386Sopenharmony_ci hash *= 0xc2b2ae35; 30cb93a386Sopenharmony_ci hash ^= hash >> 16; 31cb93a386Sopenharmony_ci return hash; 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci /** 35cb93a386Sopenharmony_ci * uint32_t -> uint32_t hash, useful for when you're about to trucate this hash but you 36cb93a386Sopenharmony_ci * suspect its low bits aren't well mixed. 37cb93a386Sopenharmony_ci * 38cb93a386Sopenharmony_ci * This version is 2-lines cheaper than Mix, but seems to be sufficient for the font cache. 39cb93a386Sopenharmony_ci */ 40cb93a386Sopenharmony_ci static uint32_t CheapMix(uint32_t hash) { 41cb93a386Sopenharmony_ci hash ^= hash >> 16; 42cb93a386Sopenharmony_ci hash *= 0x85ebca6b; 43cb93a386Sopenharmony_ci hash ^= hash >> 16; 44cb93a386Sopenharmony_ci return hash; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci}; 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci// SkGoodHash should usually be your first choice in hashing data. 49cb93a386Sopenharmony_ci// It should be both reasonably fast and high quality. 50cb93a386Sopenharmony_cistruct SkGoodHash { 51cb93a386Sopenharmony_ci template <typename K> 52cb93a386Sopenharmony_ci std::enable_if_t<sizeof(K) == 4, uint32_t> operator()(const K& k) const { 53cb93a386Sopenharmony_ci return SkChecksum::Mix(*(const uint32_t*)&k); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci template <typename K> 57cb93a386Sopenharmony_ci std::enable_if_t<sizeof(K) != 4, uint32_t> operator()(const K& k) const { 58cb93a386Sopenharmony_ci return SkOpts::hash_fn(&k, sizeof(K), 0); 59cb93a386Sopenharmony_ci } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci uint32_t operator()(const SkString& k) const { 62cb93a386Sopenharmony_ci return SkOpts::hash_fn(k.c_str(), k.size(), 0); 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci}; 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci#endif 67