libfoedus-core
FOEDUS Core Library
foedus::storage::hash::HashTmpBin Class Referencefinal

An in-memory single-threaded data structure to compose tuples in a hash bin. More...

Detailed Description

An in-memory single-threaded data structure to compose tuples in a hash bin.

This object is used in the hash composer to organize data pages for each hash bin, applying log entries to existing tuples. In essense, it is another hash-table where bucket is low-bits (while bin-bits use high-bits). For testability and modularity, we separated this to its own class.

Access pattern to optimize for
Reducer sorts hash log entries by their hash bins. In each bin, logs are sorted by timestamp. So, the inputs are not sorted by full-hash values, which would have simplified how this object indexes each tuple (just linked list is enough). Instead, we can assume that the next access on the same key surely has a larger timestamp, so this object doesn't have to worry about the order of applying modifications.

Definition at line 54 of file hash_tmpbin.hpp.

#include <hash_tmpbin.hpp>

Classes

struct  Record
 Represents a record with a unique key. More...
 

Public Types

enum  Constants { kBucketCount = 1 << 16, kDefaultInitialSize = 1 << 24 }
 
typedef uint32_t RecordIndex
 Pointer to Record. More...
 

Public Member Functions

 HashTmpBin ()
 Constructor doesn't do any initialization. More...
 
ErrorCode create_memory (uint16_t numa_node, uint64_t initial_size=kDefaultInitialSize)
 Allocates the memory to use by this object. More...
 
void release_memory ()
 Destructor automatically releases everything, but you can use this to do it earlier. More...
 
void steal_memory (memory::AlignedMemory *provider)
 This is a special version of create_memory() where this object steals the memory ownership from the recipient. More...
 
void give_memory (memory::AlignedMemory *recipient)
 This is a special version of release_memory() where this object moves the memory ownership to the recipient. More...
 
void clean ()
 Removes all tuple data for the current bin. More...
 
void clean_quick ()
 This version selectively clears buckets_ by seeing individual records. More...
 
Recordget_record (RecordIndex index) const
 
RecordIndex get_records_capacity () const
 
RecordIndex get_records_consumed () const
 
RecordIndex get_first_record () const
 
uint32_t get_physical_record_count () const
 
RecordIndex get_bucket_head (uint32_t bucket) const
 
ErrorCode insert_record (xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash, const void *payload, uint16_t payload_length)
 Inserts a new record of the given key and payload. More...
 
ErrorCode delete_record (xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash)
 Logically deletes a record of the given key. More...
 
ErrorCode overwrite_record (xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash, const void *payload, uint16_t payload_offset, uint16_t payload_count)
 Overwrites a part of the record of the given key. More...
 
ErrorCode update_record (xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash, const void *payload, uint16_t payload_length)
 Updates a record of the given key with the given payload, which might change length. More...
 

Friends

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

Member Typedef Documentation

Pointer to Record.

0 means null.

Definition at line 69 of file hash_tmpbin.hpp.

Member Enumeration Documentation

Enumerator
kBucketCount 

This is a per-bin data structure.

This should be large enough. If not, the bin has many data pages, causing low performance anyways.

kDefaultInitialSize 

Let's be super generous, assuming that we are reusing memories.

Definition at line 56 of file hash_tmpbin.hpp.

56  {
61  kBucketCount = 1 << 16,
63  kDefaultInitialSize = 1 << 24,
64  };
Let's be super generous, assuming that we are reusing memories.
Definition: hash_tmpbin.hpp:63
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61

Constructor & Destructor Documentation

foedus::storage::hash::HashTmpBin::HashTmpBin ( )

Constructor doesn't do any initialization.

You must call create_memory() before using.

Definition at line 32 of file hash_tmpbin.cpp.

33  : memory_(), records_capacity_(0), records_consumed_(0), buckets_(nullptr), records_(nullptr) {
34 }

Member Function Documentation

void foedus::storage::hash::HashTmpBin::clean ( )

Removes all tuple data for the current bin.

The memory is kept so that we can efficiently reuse resources for next bins to process.

This is a full cleaning method that can be used anytime, but costs a bit more. When there were few records, it is a bit expensive to mem-zero the entire buckets_. In that case, use clean_quick()

Definition at line 74 of file hash_tmpbin.cpp.

References get_first_record().

Referenced by create_memory(), foedus::storage::hash::HashComposeContext::execute(), give_memory(), release_memory(), and steal_memory().

74  {
75  records_consumed_ = get_first_record();
76  if (buckets_) {
77  std::memset(buckets_, 0, records_consumed_ * sizeof(Record));
78  }
79 }
RecordIndex get_first_record() const

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::hash::HashTmpBin::clean_quick ( )

This version selectively clears buckets_ by seeing individual records.

Hence, this can be used only after records_consumed_ is populated. Instead, when there are just a few records, this is much faster than clean().

Definition at line 81 of file hash_tmpbin.cpp.

References ASSERT_ND, get_first_record(), get_record(), and foedus::storage::hash::HashTmpBin::Record::hash_.

81  {
82  ASSERT_ND(buckets_);
83  ASSERT_ND(records_capacity_ > 0);
84  ASSERT_ND(records_consumed_ >= get_first_record());
85  // at some point, just mem-zero is faster. we could do a switch like below, but it's rare.
86  // this also makes unit-testing more tricky.
87  // if (records_consumed_ > get_first_record() + 256U) {
88  // clean();
89  // return;
90  // }
91  for (RecordIndex index = get_first_record(); index < records_consumed_; ++index) {
92  Record* record = get_record(index);
93  buckets_[extract_bucket(record->hash_)] = 0;
94  }
95  records_consumed_ = get_first_record();
96 }
uint32_t RecordIndex
Pointer to Record.
Definition: hash_tmpbin.hpp:69
Record * get_record(RecordIndex index) const
RecordIndex get_first_record() const
#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

Here is the call graph for this function:

ErrorCode foedus::storage::hash::HashTmpBin::create_memory ( uint16_t  numa_node,
uint64_t  initial_size = kDefaultInitialSize 
)

Allocates the memory to use by this object.

Must be called before using this object.

Parameters
[in]numa_nodethe NUMA node to allocate this object's memory on
[in]initial_sizebyte size of the memory to start from.
Precondition
initial_size > sizeof(RecordIndex)*kBucketCount, in reality should be much larger
Postcondition
!memory_->is_null()

Definition at line 36 of file hash_tmpbin.cpp.

References foedus::memory::AlignedMemory::alloc(), ASSERT_ND, clean(), kBucketCount, foedus::kErrorCodeOk, foedus::memory::AlignedMemory::kNumaAllocOnnode, and foedus::storage::kPageSize.

Referenced by foedus::storage::hash::HashComposeContext::execute().

36  {
37  ASSERT_ND(initial_size > sizeof(RecordIndex) * kBucketCount);
38  ASSERT_ND(sizeof(Record) == kPageSize);
39  memory_.alloc(
40  initial_size,
41  1ULL << 21,
43  numa_node);
44  on_memory_set();
45  clean();
46  return kErrorCodeOk;
47 }
numa_alloc_onnode() and numa_free().
uint32_t RecordIndex
Pointer to Record.
Definition: hash_tmpbin.hpp:69
void clean()
Removes all tuple data for the current bin.
Definition: hash_tmpbin.cpp:74
void alloc(uint64_t size, uint64_t alignment, AllocType alloc_type, int numa_node) noexcept
Allocate a memory, releasing the current memory if exists.
0 means no-error.
Definition: error_code.hpp:87
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61
#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
const uint16_t kPageSize
A constant defining the page size (in bytes) of both snapshot pages and volatile pages.
Definition: storage_id.hpp:45

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::hash::HashTmpBin::delete_record ( xct::XctId  xct_id,
const void *  key,
uint16_t  key_length,
HashValue  hash 
)

Logically deletes a record of the given key.

If there is no existing record of the key, or such a record is already logically deleted, this method returns an error (kErrorCodeStrKeyNotFound). Mustn't happen either.

Definition at line 167 of file hash_tmpbin.cpp.

References ASSERT_ND, foedus::xct::XctId::compare_epoch_and_orginal(), get_record(), foedus::storage::hash::HashTmpBin::Record::hash_, foedus::storage::hash::hashinate(), foedus::xct::XctId::is_deleted(), foedus::kErrorCodeOk, foedus::kErrorCodeStrKeyNotFound, UNLIKELY, and foedus::storage::hash::HashTmpBin::Record::xct_id_.

171  {
172  ASSERT_ND(xct_id.is_deleted());
173  ASSERT_ND(hashinate(key, key_length) == hash);
174  SearchResult result = search_bucket(key, key_length, hash);
175  if (UNLIKELY(result.found_ == 0)) {
176  DLOG(WARNING) << "HashTmpBin::delete_record() hit KeyNotFound case 1. This must not"
177  << " happen except unit testcases.";
179  } else {
180  Record* record = get_record(result.found_);
181  ASSERT_ND(record->hash_ == hash);
182  if (UNLIKELY(record->xct_id_.is_deleted())) {
183  DLOG(WARNING) << "HashTmpBin::delete_record() hit KeyNotFound case 2. This must not"
184  << " happen except unit testcases.";
186  }
187  ASSERT_ND(record->xct_id_.compare_epoch_and_orginal(xct_id) < 0);
188  record->xct_id_ = xct_id;
189  }
190 
191  return kErrorCodeOk;
192 }
0x080C : "STORAGE: This key is not found in this storage" .
Definition: error_code.hpp:178
0 means no-error.
Definition: error_code.hpp:87
HashValue hashinate(const void *key, uint16_t key_length)
Calculates hash value for general input.
Record * get_record(RecordIndex index) const
#define UNLIKELY(x)
Hints that x is highly likely false.
Definition: compiler.hpp:104
#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

Here is the call graph for this function:

RecordIndex foedus::storage::hash::HashTmpBin::get_bucket_head ( uint32_t  bucket) const
inline

Definition at line 211 of file hash_tmpbin.hpp.

References ASSERT_ND, and kBucketCount.

211  {
212  ASSERT_ND(bucket < kBucketCount);
213  return buckets_[bucket];
214  }
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61
#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
RecordIndex foedus::storage::hash::HashTmpBin::get_first_record ( ) const
inline

Definition at line 204 of file hash_tmpbin.hpp.

References kBucketCount.

Referenced by clean(), clean_quick(), get_physical_record_count(), and foedus::storage::hash::operator<<().

204  {
205  return sizeof(RecordIndex) * kBucketCount / sizeof(Record);
206  }
uint32_t RecordIndex
Pointer to Record.
Definition: hash_tmpbin.hpp:69
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61

Here is the caller graph for this function:

uint32_t foedus::storage::hash::HashTmpBin::get_physical_record_count ( ) const
inline
Returns
number of physical records, which may or may not be logically deleted

Definition at line 208 of file hash_tmpbin.hpp.

References get_first_record(), and get_records_consumed().

208  {
210  }
RecordIndex get_records_consumed() const
RecordIndex get_first_record() const

Here is the call graph for this function:

Record* foedus::storage::hash::HashTmpBin::get_record ( RecordIndex  index) const
inline

Definition at line 197 of file hash_tmpbin.hpp.

References ASSERT_ND, and kBucketCount.

Referenced by clean_quick(), delete_record(), insert_record(), foedus::storage::hash::operator<<(), overwrite_record(), and update_record().

197  {
198  ASSERT_ND(index < records_capacity_);
199  ASSERT_ND(index >= sizeof(RecordIndex) * kBucketCount / sizeof(Record));
200  return records_ + index;
201  }
uint32_t RecordIndex
Pointer to Record.
Definition: hash_tmpbin.hpp:69
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61
#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

Here is the caller graph for this function:

RecordIndex foedus::storage::hash::HashTmpBin::get_records_capacity ( ) const
inline

Definition at line 202 of file hash_tmpbin.hpp.

202 { return records_capacity_; }
RecordIndex foedus::storage::hash::HashTmpBin::get_records_consumed ( ) const
inline

Definition at line 203 of file hash_tmpbin.hpp.

Referenced by get_physical_record_count(), and foedus::storage::hash::operator<<().

203 { return records_consumed_; }

Here is the caller graph for this function:

void foedus::storage::hash::HashTmpBin::give_memory ( memory::AlignedMemory recipient)

This is a special version of release_memory() where this object moves the memory ownership to the recipient.

Combined with steal_memory(), this allows completely reusing memory.

Parameters
[in,out]recipientthe memory to receive the ownership of memory this object has
Precondition
!memory_->is_null()
Postcondition
!recipient->is_null()
memory_->is_null()

Definition at line 64 of file hash_tmpbin.cpp.

References ASSERT_ND, clean(), and foedus::memory::AlignedMemory::is_null().

64  {
65  ASSERT_ND(!memory_.is_null());
66  *recipient = std::move(memory_);
67  ASSERT_ND(!recipient->is_null());
68  ASSERT_ND(memory_.is_null());
69  on_memory_set();
70  clean();
71 }
void clean()
Removes all tuple data for the current bin.
Definition: hash_tmpbin.cpp:74
#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
bool is_null() const
Returns if this object doesn't hold a valid memory block.

Here is the call graph for this function:

ErrorCode foedus::storage::hash::HashTmpBin::insert_record ( xct::XctId  xct_id,
const void *  key,
uint16_t  key_length,
HashValue  hash,
const void *  payload,
uint16_t  payload_length 
)

Inserts a new record of the given key and payload.

If there is an existing record of the key that is logically deleted, we flip the deletion flag. If such an record exists and also is not logically deleted, this method returns an error (kErrorCodeStrKeyAlreadyExists). Considering how this object is used, it mustn't hapepn.

Definition at line 126 of file hash_tmpbin.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::xct::XctId::compare_epoch_and_orginal(), get_record(), foedus::storage::hash::HashTmpBin::Record::hash_, foedus::storage::hash::hashinate(), foedus::xct::XctId::is_deleted(), foedus::kErrorCodeOk, foedus::kErrorCodeStrKeyAlreadyExists, foedus::storage::hash::HashTmpBin::Record::next_, foedus::storage::hash::HashTmpBin::Record::set_all(), foedus::storage::hash::HashTmpBin::Record::set_payload(), UNLIKELY, and foedus::storage::hash::HashTmpBin::Record::xct_id_.

132  {
133  ASSERT_ND(!xct_id.is_deleted());
134  ASSERT_ND(hashinate(key, key_length) == hash);
135  SearchResult result = search_bucket(key, key_length, hash);
136  if (result.found_ == 0) {
137  RecordIndex new_index;
138  CHECK_ERROR_CODE(alloc_record(&new_index));
139  Record* record = get_record(new_index);
140  record->set_all(xct_id, key, key_length, hash, payload, payload_length);
141 
142  if (result.tail_ == 0) {
143  uint16_t bucket_index = extract_bucket(hash);
144  ASSERT_ND(buckets_[bucket_index] == 0);
145  buckets_[bucket_index] = new_index;
146  } else {
147  ASSERT_ND(buckets_[extract_bucket(hash)] != 0);
148  Record* tail_record = get_record(result.tail_);
149  tail_record->next_ = new_index;
150  }
151  } else {
152  Record* record = get_record(result.found_);
153  ASSERT_ND(record->hash_ == hash);
154  if (UNLIKELY(!record->xct_id_.is_deleted())) {
155  DLOG(WARNING) << "HashTmpBin::insert_record() hit KeyAlreadyExists case. This must not"
156  << " happen except unit testcases.";
158  }
159  ASSERT_ND(record->xct_id_.compare_epoch_and_orginal(xct_id) < 0);
160  record->xct_id_ = xct_id;
161  record->set_payload(payload, payload_length);
162  }
163 
164  return kErrorCodeOk;
165 }
uint32_t RecordIndex
Pointer to Record.
Definition: hash_tmpbin.hpp:69
0 means no-error.
Definition: error_code.hpp:87
HashValue hashinate(const void *key, uint16_t key_length)
Calculates hash value for general input.
Record * get_record(RecordIndex index) const
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#define UNLIKELY(x)
Hints that x is highly likely false.
Definition: compiler.hpp:104
#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
0x080B : "STORAGE: This key already exists in this storage" .
Definition: error_code.hpp:177

Here is the call graph for this function:

ErrorCode foedus::storage::hash::HashTmpBin::overwrite_record ( xct::XctId  xct_id,
const void *  key,
uint16_t  key_length,
HashValue  hash,
const void *  payload,
uint16_t  payload_offset,
uint16_t  payload_count 
)

Overwrites a part of the record of the given key.

If there is no existing record of the key, or such a record is already logically deleted, this method returns an error (kErrorCodeStrKeyNotFound). Mustn't happen either.

Definition at line 194 of file hash_tmpbin.cpp.

References ASSERT_ND, foedus::xct::XctId::compare_epoch_and_orginal(), get_record(), foedus::storage::hash::HashTmpBin::Record::hash_, foedus::storage::hash::hashinate(), foedus::xct::XctId::is_deleted(), foedus::kErrorCodeOk, foedus::kErrorCodeStrKeyNotFound, foedus::kErrorCodeStrTooShortPayload, foedus::storage::hash::HashTmpBin::Record::overwrite_payload(), foedus::storage::hash::HashTmpBin::Record::payload_length_, UNLIKELY, and foedus::storage::hash::HashTmpBin::Record::xct_id_.

201  {
202  ASSERT_ND(!xct_id.is_deleted());
203  ASSERT_ND(hashinate(key, key_length) == hash);
204  SearchResult result = search_bucket(key, key_length, hash);
205  if (UNLIKELY(result.found_ == 0)) {
206  DLOG(WARNING) << "HashTmpBin::overwrite_record() hit KeyNotFound case 1. This must not"
207  << " happen except unit testcases.";
209  } else {
210  Record* record = get_record(result.found_);
211  ASSERT_ND(record->hash_ == hash);
212  if (UNLIKELY(record->xct_id_.is_deleted())) {
213  DLOG(WARNING) << "HashTmpBin::overwrite_record() hit KeyNotFound case 2. This must not"
214  << " happen except unit testcases.";
216  } else if (UNLIKELY(record->payload_length_ < payload_offset + payload_count)) {
217  DLOG(WARNING) << "HashTmpBin::overwrite_record() hit TooShortPayload case. This must not"
218  << " happen except unit testcases.";
220  }
221  ASSERT_ND(record->xct_id_.compare_epoch_and_orginal(xct_id) < 0);
222  record->xct_id_ = xct_id;
223  record->overwrite_payload(payload, payload_offset, payload_count);
224  }
225 
226  return kErrorCodeOk;
227 }
0x080A : "STORAGE: The record's payload is smaller than requested" .
Definition: error_code.hpp:176
0x080C : "STORAGE: This key is not found in this storage" .
Definition: error_code.hpp:178
0 means no-error.
Definition: error_code.hpp:87
HashValue hashinate(const void *key, uint16_t key_length)
Calculates hash value for general input.
Record * get_record(RecordIndex index) const
#define UNLIKELY(x)
Hints that x is highly likely false.
Definition: compiler.hpp:104
#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

Here is the call graph for this function:

void foedus::storage::hash::HashTmpBin::release_memory ( )

Destructor automatically releases everything, but you can use this to do it earlier.

Definition at line 49 of file hash_tmpbin.cpp.

References clean(), and foedus::memory::AlignedMemory::release_block().

49  {
50  memory_.release_block();
51  on_memory_set();
52  clean();
53 }
void release_block()
Releases the memory block.
void clean()
Removes all tuple data for the current bin.
Definition: hash_tmpbin.cpp:74

Here is the call graph for this function:

void foedus::storage::hash::HashTmpBin::steal_memory ( memory::AlignedMemory provider)

This is a special version of create_memory() where this object steals the memory ownership from the recipient.

Combined with give_memory(), this allows completely reusing memory.

Parameters
[in,out]providerthe memory from which this object steals ownership
Precondition
!provider->is_null()
Postcondition
provider->is_null()
!memory_->is_null()

Definition at line 55 of file hash_tmpbin.cpp.

References ASSERT_ND, clean(), and foedus::memory::AlignedMemory::is_null().

55  {
56  ASSERT_ND(!provider->is_null());
57  memory_ = std::move(*provider);
58  ASSERT_ND(provider->is_null());
59  ASSERT_ND(!memory_.is_null());
60  on_memory_set();
61  clean();
62 }
void clean()
Removes all tuple data for the current bin.
Definition: hash_tmpbin.cpp:74
#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

Here is the call graph for this function:

ErrorCode foedus::storage::hash::HashTmpBin::update_record ( xct::XctId  xct_id,
const void *  key,
uint16_t  key_length,
HashValue  hash,
const void *  payload,
uint16_t  payload_length 
)

Updates a record of the given key with the given payload, which might change length.

This method is same as delete_record()+insert_record(). The difference is that this can be faster because it does only one lookup. If there is no existing record of the key, or such a record is already logically deleted, this method returns an error (kErrorCodeStrKeyNotFound). Mustn't happen either.

Definition at line 229 of file hash_tmpbin.cpp.

References ASSERT_ND, foedus::xct::XctId::compare_epoch_and_orginal(), get_record(), foedus::storage::hash::HashTmpBin::Record::hash_, foedus::storage::hash::hashinate(), foedus::xct::XctId::is_deleted(), foedus::kErrorCodeOk, foedus::kErrorCodeStrKeyNotFound, foedus::storage::hash::HashTmpBin::Record::set_payload(), UNLIKELY, and foedus::storage::hash::HashTmpBin::Record::xct_id_.

235  {
236  ASSERT_ND(!xct_id.is_deleted());
237  ASSERT_ND(hashinate(key, key_length) == hash);
238  SearchResult result = search_bucket(key, key_length, hash);
239  if (UNLIKELY(result.found_ == 0)) {
240  DLOG(WARNING) << "HashTmpBin::update_record() hit KeyNotFound case 1. This must not"
241  << " happen except unit testcases.";
243  } else {
244  Record* record = get_record(result.found_);
245  ASSERT_ND(record->hash_ == hash);
246  if (UNLIKELY(record->xct_id_.is_deleted())) {
247  DLOG(WARNING) << "HashTmpBin::update_record() hit KeyNotFound case 2. This must not"
248  << " happen except unit testcases.";
250  }
251  ASSERT_ND(record->xct_id_.compare_epoch_and_orginal(xct_id) < 0);
252  record->xct_id_ = xct_id;
253  record->set_payload(payload, payload_length);
254  }
255 
256  return kErrorCodeOk;
257 }
0x080C : "STORAGE: This key is not found in this storage" .
Definition: error_code.hpp:178
0 means no-error.
Definition: error_code.hpp:87
HashValue hashinate(const void *key, uint16_t key_length)
Calculates hash value for general input.
Record * get_record(RecordIndex index) const
#define UNLIKELY(x)
Hints that x is highly likely false.
Definition: compiler.hpp:104
#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

Here is the call graph for this function:

Friends And Related Function Documentation

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

Definition at line 287 of file hash_tmpbin.cpp.

287  {
288  // Each bin shouldn't have that many records... so, output everything!
289  o << "<HashTmpBin>" << std::endl;
290  o << " " << v.memory_ << std::endl;
291  o << " <records_capacity_>" << v.records_capacity_ << "</records_capacity_>" << std::endl;
292  o << " <records_consumed_>" << v.records_consumed_ << "</records_consumed_>" << std::endl;
293  o << " <buckets_>" << std::endl;
294  for (uint32_t i = 0; i < HashTmpBin::kBucketCount; ++i) {
295  if (v.buckets_[i] != 0) {
296  o << " <bucket idx=\"" << i << "\" head_rec=\"" << v.buckets_[i] << "\" />" << std::endl;
297  }
298  }
299  o << " </buckets_>" << std::endl;
300  o << " <records_>" << std::endl;
301  uint32_t begin = v.get_first_record();
302  for (uint32_t i = begin; i < v.get_records_consumed(); ++i) {
303  HashTmpBin::Record* record = v.get_record(i);
304  o << " <record id=\"" << i << "\" hash=\"" << assorted::Hex(record->hash_, 16) << "\"";
305  if (record->next_) {
306  o << " next_rec=\"" << record->next_ << "\"";
307  }
308  o << ">";
309  o << "<key>" << assorted::HexString(std::string(record->get_key(), record->key_length_))
310  << "</key>";
311  o << "<payload>"
312  << assorted::HexString(std::string(record->get_payload(), record->payload_length_))
313  << "</payload>";
314  o << record->xct_id_;
315  o << "</record>" << std::endl;
316  }
317  o << " </records_>" << std::endl;
318  o << "</HashTmpBin>";
319  return o;
320 }
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61

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