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