libfoedus-core
FOEDUS Core Library
foedus::cache::HashFunc Struct Referencefinal

A simple hash function logic used in snasphot cache. More...

Detailed Description

A simple hash function logic used in snasphot cache.

The hash key is SnapshotPagePointer, whose least significant bits are local page IDs, which are sequnetial. To avoid placing adjacent page IDs in adjacent hash buckets, we use byte-swap and a few bit shifts, then divide by logical table size which is adjusted to an almost-prime number.

Definition at line 90 of file cache_hashtable.hpp.

#include <cache_hashtable.hpp>

Collaboration diagram for foedus::cache::HashFunc:

Public Member Functions

 HashFunc (BucketId physical_buckets)
 
BucketId get_bucket_number (storage::SnapshotPagePointer page_id) const __attribute__((always_inline))
 Returns a bucket number the given snapshot page ID should belong to. More...
 

Static Public Member Functions

static uint32_t get_hash (storage::SnapshotPagePointer page_id) __attribute__((always_inline))
 Returns a hash value for the given snapshot page ID. More...
 
static PageIdTag get_tag (storage::SnapshotPagePointer page_id) __attribute__((always_inline))
 Returns another hash value used to differentiate IDs with similar hash values. More...
 

Public Attributes

const BucketId logical_buckets_
 Number of logical (actually used) buckets in this table. More...
 
const BucketId physical_buckets_
 Number of buckets that are physically allocated, at least kHopNeighbors more than logical. More...
 
const assorted::ConstDiv bucket_div_
 to efficiently divide a number by bucket_div_. More...
 

Friends

std::ostream & operator<< (std::ostream &o, const HashFunc &v)
 

Constructor & Destructor Documentation

foedus::cache::HashFunc::HashFunc ( BucketId  physical_buckets)
explicit

Definition at line 60 of file cache_hashtable.cpp.

61  : logical_buckets_(determine_logical_buckets(physical_buckets)),
62  physical_buckets_(physical_buckets),
64 }
const BucketId logical_buckets_
Number of logical (actually used) buckets in this table.
BucketId determine_logical_buckets(BucketId physical_buckets)
const assorted::ConstDiv bucket_div_
to efficiently divide a number by bucket_div_.
const BucketId physical_buckets_
Number of buckets that are physically allocated, at least kHopNeighbors more than logical...

Member Function Documentation

BucketId foedus::cache::HashFunc::get_bucket_number ( storage::SnapshotPagePointer  page_id) const
inline

Returns a bucket number the given snapshot page ID should belong to.

Definition at line 110 of file cache_hashtable.hpp.

References ASSERT_ND, foedus::assorted::ConstDiv::div32(), get_hash(), and foedus::assorted::ConstDiv::rem32().

Referenced by foedus::cache::CacheHashtable::get_bucket_number().

110  {
111  uint32_t seed = get_hash(page_id);
112  uint32_t quotient = bucket_div_.div32(seed);
113  uint32_t bucket = bucket_div_.rem32(seed, logical_buckets_, quotient);
114  ASSERT_ND(bucket == seed % logical_buckets_);
115  return bucket;
116  }
const BucketId logical_buckets_
Number of logical (actually used) buckets in this table.
uint32_t rem32(uint32_t n, uint32_t d, uint32_t q) const
Calculate remainder.
Definition: const_div.hpp:205
static uint32_t get_hash(storage::SnapshotPagePointer page_id) __attribute__((always_inline))
Returns a hash value for the given snapshot page ID.
const assorted::ConstDiv bucket_div_
to efficiently divide a number by bucket_div_.
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
uint32_t div32(uint32_t n) const
32-bit integer division that outputs both quotient and remainder.
Definition: const_div.hpp:228

Here is the call graph for this function:

Here is the caller graph for this function:

uint32_t foedus::cache::HashFunc::get_hash ( storage::SnapshotPagePointer  page_id)
inlinestatic

Returns a hash value for the given snapshot page ID.

This needs no member variables.

Definition at line 384 of file cache_hashtable.hpp.

References foedus::storage::extract_local_page_id_from_snapshot_pointer(), foedus::storage::extract_numa_node_from_snapshot_pointer(), and foedus::storage::extract_snapshot_id_from_snapshot_pointer().

Referenced by get_bucket_number().

384  {
385  uint16_t snapshot_id = storage::extract_snapshot_id_from_snapshot_pointer(page_id);
386  uint8_t numa_node = storage::extract_numa_node_from_snapshot_pointer(page_id);
387  uint64_t local_page_id = storage::extract_local_page_id_from_snapshot_pointer(page_id);
388  // snapshot_id is usually very sparse. and has no correlation with local_page_id.
389  // numa_node too. thus just use them as seeds for good old multiplicative hashing.
390  uint32_t seed = snapshot_id * 0x5a2948074497175aULL;
391  seed += numa_node * 0xc30a95f6e63dd908ULL;
392 
393  // local_page_id is 40 bits. 32-40 bits are very sparse, and it has no correlation with
394  // other bits (how come 4kb-th page and 16Tb+4kb-th page has anything in common..).
395  // so, let's treat it with another multiplicative.
396  uint8_t highest_bits = static_cast<uint8_t>(local_page_id >> 32);
397  uint32_t folded_local_page_id = local_page_id + highest_bits * 0xd3561f5bedac324cULL;
398 
399  // now, we don't want to place adjacent pages in adjacent hash buckets. so, let's swap bytes.
400  // this benefits hop-scotch hashing table.
401  uint32_t swaped_page_id = __builtin_bswap32(folded_local_page_id);
402  seed ^= swaped_page_id;
403  return seed;
404 }
SnapshotLocalPageId extract_local_page_id_from_snapshot_pointer(SnapshotPagePointer pointer)
Definition: storage_id.hpp:91
uint16_t extract_snapshot_id_from_snapshot_pointer(SnapshotPagePointer pointer)
Definition: storage_id.hpp:98
uint8_t extract_numa_node_from_snapshot_pointer(SnapshotPagePointer pointer)
Definition: storage_id.hpp:95

Here is the call graph for this function:

Here is the caller graph for this function:

PageIdTag foedus::cache::HashFunc::get_tag ( storage::SnapshotPagePointer  page_id)
inlinestatic

Returns another hash value used to differentiate IDs with similar hash values.

Definition at line 406 of file cache_hashtable.hpp.

Referenced by foedus::cache::CacheHashtable::find(), foedus::cache::CacheHashtable::find_batch(), and foedus::cache::CacheHashtable::install().

406  {
407  PageIdTag high_bits = static_cast<PageIdTag>(page_id >> 32);
408  PageIdTag tag = high_bits * 0x8e1d76486c3e638dULL + static_cast<PageIdTag>(page_id);
409  if (tag == 0) {
410  tag = 1; // we avoid 0 as a valid value. this enables sanity checks.
411  }
412  return tag;
413 }
uint32_t PageIdTag
This is a lossy-compressed representation of SnapshotPagePointer used to quickly identify whether the...

Here is the caller graph for this function:

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  o,
const HashFunc v 
)
friend

Definition at line 332 of file cache_hashtable.cpp.

332  {
333  o << "<HashFunc>"
334  << "<logical_buckets_>" << v.logical_buckets_ << "<logical_buckets_>"
335  << "<physical_buckets_>" << v.physical_buckets_ << "<physical_buckets_>"
336  << "</HashFunc>";
337  return o;
338 }

Member Data Documentation

const assorted::ConstDiv foedus::cache::HashFunc::bucket_div_

to efficiently divide a number by bucket_div_.

Definition at line 96 of file cache_hashtable.hpp.

const BucketId foedus::cache::HashFunc::logical_buckets_

Number of logical (actually used) buckets in this table.

Definition at line 92 of file cache_hashtable.hpp.

Referenced by foedus::cache::CacheHashtable::get_logical_buckets(), and foedus::cache::operator<<().

const BucketId foedus::cache::HashFunc::physical_buckets_

Number of buckets that are physically allocated, at least kHopNeighbors more than logical.

Definition at line 94 of file cache_hashtable.hpp.

Referenced by foedus::cache::CacheHashtable::get_physical_buckets(), and foedus::cache::operator<<().


The documentation for this struct was generated from the following files: