HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TfHash Class Reference

#include <hash.h>

Public Member Functions

template<class T >
auto operator() (T &&obj) const -> decltype(Tf_HashImpl(std::declval< Tf_HashState & >(), std::forward< T >(obj), 0), size_t())
 

Detailed Description

A user-extensible hashing mechanism for use with runtime hash tables.

The hash functions here are appropriate for storing objects in runtime hash tables. They are not appropriate for document signatures / fingerprinting or for storage and offline use. No specific guarantee is made about hash function quality, and the resulting hash codes are only 64-bits wide. Callers must assume that collisions will occur and be prepared to deal with them.

Additionally, no guarantee is made about repeatability from run-to-run. That is, within a process lifetime an object's hash code will not change (provided its internal state does not change). But an object with equivalent state in a future run of the same process may hash differently.

At the time of this writing we observe good performance combined with the "avalanche" quality (~50% output bit flip probability for a single input bit flip) in the low-order 40 output bits. Higher order bits do not achieve avalanche, and the highest order 8 bits are particularly poor. But for our purposes we deem this performance/quality tradeoff acceptable.

This mechanism has builtin support for integral and floating point types, some STL types and types in Tf. TfHash uses three methods to attempt to hash a passed object. First, TfHash tries to call TfHashAppend() on its argument. This is the primary customization point for TfHash. If that is not viable, TfHash makes an unqualified call to hash_value(). We would like TfHash to try to use std::hash<T> next, but std::hash<T> is not SFINAE-friendly until c++17, and this code needs to support c++14.

The best way to add TfHash support for user-defined types is to provide a function overload like the following.

template <class HashState>
void TfHashAppend(HashState &h, MyType const &myObj)
h.Append(myObject._member1);
h.Append(myObject._member2);
h.Append(myObject._member3);
h.AppendContiguous(myObject._memberArray, myObject._numArrayElems);
}

The HashState object is left deliberately unspecified, so that different hash state objects may be used in different circumstances without modifying this support code, and without excess abstraction penalty. The methods available for use in TfHashAppend overloads are:

// Append one object to the hash state. This invokes the TfHash mechanism
// so it works for any type that is supported by TfHash.
template <class T>
void HashState::Append(T &&obj);
// Append contiguous objects to the hash state. Note that this is
// explicitly *not* guaranteed to produce the same result as calling
// Append() with each object in order.
template <class T>
void HashState::AppendContiguous(T const *objects, size_t numObjects);

The TfHash class function object supports:

  • integral types (including bool)
  • floating point types
  • std::string
  • TfRefPtr
  • TfWeakPtr
  • TfEnum
  • const void*
  • types that provide overloads for TfHashAppend
  • types that provide overloads for hash_value

The TfHash class can be used to instantiate a TfHashMap with string keys as follows:

TfHash()(const char*) is disallowed to avoid confusion of whether the pointer or the string is being hashed. If you want to hash a C-string use TfHashCString and if you want to hash a char* use TfHashCharPtr.

Definition at line 366 of file hash.h.

Member Function Documentation

template<class T >
auto TfHash::operator() ( T &&  obj) const -> decltype(Tf_HashImpl(std::declval<Tf_HashState &>(), std::forward<T>(obj), 0), size_t())
inline

Produce a hash code for obj. See the class documentation for details.

Definition at line 371 of file hash.h.


The documentation for this class was generated from the following file: