Home | History | Annotate | Download | only in flatbuffers
      1 /*
      2  * Copyright 2015 Google Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef FLATBUFFERS_HASH_H_
     18 #define FLATBUFFERS_HASH_H_
     19 
     20 #include <cstdint>
     21 #include <cstring>
     22 
     23 #include "flatbuffers/flatbuffers.h"
     24 
     25 namespace flatbuffers {
     26 
     27 template <typename T>
     28 struct FnvTraits {
     29   static const T kFnvPrime;
     30   static const T kOffsetBasis;
     31 };
     32 
     33 template <>
     34 struct FnvTraits<uint32_t> {
     35   static const uint32_t kFnvPrime = 0x01000193;
     36   static const uint32_t kOffsetBasis = 0x811C9DC5;
     37 };
     38 
     39 template <>
     40 struct FnvTraits<uint64_t> {
     41   static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
     42   static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
     43 };
     44 
     45 template <typename T>
     46 T HashFnv1(const char *input) {
     47   T hash = FnvTraits<T>::kOffsetBasis;
     48   for (const char *c = input; *c; ++c) {
     49     hash *= FnvTraits<T>::kFnvPrime;
     50     hash ^= static_cast<unsigned char>(*c);
     51   }
     52   return hash;
     53 }
     54 
     55 template <typename T>
     56 T HashFnv1a(const char *input) {
     57   T hash = FnvTraits<T>::kOffsetBasis;
     58   for (const char *c = input; *c; ++c) {
     59     hash ^= static_cast<unsigned char>(*c);
     60     hash *= FnvTraits<T>::kFnvPrime;
     61   }
     62   return hash;
     63 }
     64 
     65 template <typename T>
     66 struct NamedHashFunction {
     67   const char *name;
     68 
     69   typedef T (*HashFunction)(const char*);
     70   HashFunction function;
     71 };
     72 
     73 const NamedHashFunction<uint32_t> kHashFunctions32[] = {
     74   { "fnv1_32",  HashFnv1<uint32_t> },
     75   { "fnv1a_32", HashFnv1a<uint32_t> },
     76 };
     77 
     78 const NamedHashFunction<uint64_t> kHashFunctions64[] = {
     79   { "fnv1_64",  HashFnv1<uint64_t> },
     80   { "fnv1a_64", HashFnv1a<uint64_t> },
     81 };
     82 
     83 inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
     84     const char *name) {
     85   std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
     86   for (std::size_t i = 0; i < size; ++i) {
     87     if (std::strcmp(name, kHashFunctions32[i].name) == 0) {
     88       return kHashFunctions32[i].function;
     89     }
     90   }
     91   return nullptr;
     92 }
     93 
     94 inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64(
     95     const char *name) {
     96   std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]);
     97   for (std::size_t i = 0; i < size; ++i) {
     98     if (std::strcmp(name, kHashFunctions64[i].name) == 0) {
     99       return kHashFunctions64[i].function;
    100     }
    101   }
    102   return nullptr;
    103 }
    104 
    105 }  // namespace flatbuffers
    106 
    107 #endif  // FLATBUFFERS_HASH_H_
    108