Harden failure signal handler in the face of memory corruptions
[folly.git] / folly / Hash.h
index 132ad846edda98a359107bc8cadd3703d2074a32..a57bbbe05a65a63d2dd9822ce2de47ca12751d27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 #include <stdint.h>
 #include <string>
 #include <utility>
+#include <tuple>
 
 #include "folly/SpookyHashV1.h"
 #include "folly/SpookyHashV2.h"
@@ -189,7 +190,7 @@ inline uint32_t jenkins_rev_unmix32(uint32_t key) {
  *     http://www.isthe.com/chongo/tech/comp/fnv/
  */
 
-const uint32_t FNV_32_HASH_START = 216613626UL;
+const uint32_t FNV_32_HASH_START = 2166136261UL;
 const uint64_t FNV_64_HASH_START = 14695981039346656037ULL;
 
 inline uint32_t fnv32(const char* s,
@@ -217,7 +218,7 @@ inline uint32_t fnv32_buf(const void* buf,
 }
 
 inline uint32_t fnv32(const std::string& str,
-                      uint64_t hash = FNV_32_HASH_START) {
+                      uint32_t hash = FNV_32_HASH_START) {
   return fnv32_buf(str.data(), str.size(), hash);
 }
 
@@ -348,6 +349,26 @@ template<> struct hasher<uint64_t> {
   }
 };
 
+// recursion
+template <size_t index, typename... Ts>
+struct TupleHasher {
+  size_t operator()(std::tuple<Ts...> const& key) const {
+    return hash::hash_combine(
+      TupleHasher<index - 1, Ts...>()(key),
+      std::get<index>(key));
+  }
+};
+
+// base
+template <typename... Ts>
+struct TupleHasher<0, Ts...> {
+  size_t operator()(std::tuple<Ts...> const& key) const {
+    // we could do std::hash here directly, but hash_combine hides all the
+    // ugly templating implicitly
+    return hash::hash_combine(std::get<0>(key));
+  }
+};
+
 } // namespace folly
 
 // Custom hash functions.
@@ -361,6 +382,18 @@ namespace std {
       return folly::hash::hash_combine(x.first, x.second);
     }
   };
+
+  // Hash function for tuples. Requires default hash functions for all types.
+  template <typename... Ts>
+  struct hash<std::tuple<Ts...>> {
+    size_t operator()(std::tuple<Ts...> const& key) const {
+      folly::TupleHasher<
+        std::tuple_size<std::tuple<Ts...>>::value - 1, // start index
+        Ts...> hasher;
+
+      return hasher(key);
+    }
+  };
 } // namespace std
 
 #endif