libfoedus-core
FOEDUS Core Library
hash_tmpbin.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
18 #ifndef FOEDUS_STORAGE_HASH_HASH_TMPBIN_HPP_
19 #define FOEDUS_STORAGE_HASH_HASH_TMPBIN_HPP_
20 
21 #include <stdint.h>
22 
23 #include <iosfwd>
24 
25 #include "foedus/compiler.hpp"
26 #include "foedus/cxx11.hpp"
32 #include "foedus/xct/xct_id.hpp"
33 
34 namespace foedus {
35 namespace storage {
36 namespace hash {
37 
55  public:
56  enum Constants {
61  kBucketCount = 1 << 16,
64  };
65 
69  typedef uint32_t RecordIndex;
70 
78  struct Record {
79  xct::XctId xct_id_; // +8 -> 8
80  uint16_t key_length_; // +2 -> 10
81  uint16_t payload_length_; // +2 -> 12
82  uint16_t aligned_key_length_; // +2 -> 14
83  uint16_t aligned_payload_length_; // +2 -> 16
84  HashValue hash_; // +8 -> 24
86  RecordIndex next_; // +4 -> 28
87  uint32_t unused_; // +4 -> 32
89  char data_[kPageSize - 32]; // -> kPageSize
90 
91  inline char* get_key() ALWAYS_INLINE { return data_; }
92  inline char* get_payload() ALWAYS_INLINE { return data_ + aligned_key_length_; }
93  inline Record* get_record_next(const HashTmpBin* enclosure) const ALWAYS_INLINE {
94  return enclosure->get_record(next_);
95  }
96 
97  inline void set_all(
98  xct::XctId xct_id,
99  const void* key,
100  uint16_t key_length,
101  HashValue hash,
102  const void* payload,
103  uint16_t payload_length) ALWAYS_INLINE {
104  xct_id_ = xct_id;
105  ASSERT_ND(!xct_id.is_deleted());
106  key_length_ = key_length;
107  payload_length_ = payload_length;
108  aligned_key_length_ = assorted::align8(key_length);
109  aligned_payload_length_ = assorted::align8(payload_length);
110  hash_ = hash;
111  next_ = 0;
112 
113  std::memcpy(get_key(), key, key_length);
114  if (key_length != aligned_key_length_) {
115  std::memset(get_key() + key_length, 0, aligned_key_length_ - key_length);
116  }
117 
118  std::memcpy(get_payload(), payload, payload_length);
119  if (payload_length != aligned_payload_length_) {
120  std::memset(get_payload() + payload_length, 0, aligned_payload_length_ - payload_length);
121  }
122  }
123 
124  inline void set_payload(const void* payload, uint16_t payload_length) ALWAYS_INLINE {
125  payload_length_ = payload_length;
126  aligned_payload_length_ = assorted::align8(payload_length);
127 
128  std::memcpy(get_payload(), payload, payload_length);
129  if (payload_length != aligned_payload_length_) {
130  std::memset(get_payload() + payload_length, 0, aligned_payload_length_ - payload_length);
131  }
132  }
133  inline void overwrite_payload(
134  const void* payload,
135  uint16_t payload_offset,
136  uint16_t payload_count) ALWAYS_INLINE {
137  std::memcpy(get_payload() + payload_offset, payload, payload_count);
138  }
139  };
140 
142 
146  HashTmpBin();
147 
155  ErrorCode create_memory(uint16_t numa_node, uint64_t initial_size = kDefaultInitialSize);
156 
158  void release_memory();
159 
168  void steal_memory(memory::AlignedMemory* provider);
169 
178  void give_memory(memory::AlignedMemory* recipient);
179 
188  void clean();
194  void clean_quick();
195 
197  Record* get_record(RecordIndex index) const {
198  ASSERT_ND(index < records_capacity_);
199  ASSERT_ND(index >= sizeof(RecordIndex) * kBucketCount / sizeof(Record));
200  return records_ + index;
201  }
202  RecordIndex get_records_capacity() const { return records_capacity_; }
203  RecordIndex get_records_consumed() const { return records_consumed_; }
204  RecordIndex get_first_record() const {
205  return sizeof(RecordIndex) * kBucketCount / sizeof(Record);
206  }
208  uint32_t get_physical_record_count() const {
210  }
211  RecordIndex get_bucket_head(uint32_t bucket) const {
212  ASSERT_ND(bucket < kBucketCount);
213  return buckets_[bucket];
214  }
215 
217 
226  xct::XctId xct_id,
227  const void* key,
228  uint16_t key_length,
229  HashValue hash,
230  const void* payload,
231  uint16_t payload_length);
232 
240  xct::XctId xct_id,
241  const void* key,
242  uint16_t key_length,
243  HashValue hash);
244 
252  xct::XctId xct_id,
253  const void* key,
254  uint16_t key_length,
255  HashValue hash,
256  const void* payload,
257  uint16_t payload_offset,
258  uint16_t payload_count);
259 
269  xct::XctId xct_id,
270  const void* key,
271  uint16_t key_length,
272  HashValue hash,
273  const void* payload,
274  uint16_t payload_length);
275 
276  friend std::ostream& operator<<(std::ostream& o, const HashTmpBin& v);
277 
278  private:
284  memory::AlignedMemory memory_;
285 
290  RecordIndex records_capacity_;
296  RecordIndex records_consumed_;
297 
302  RecordIndex* buckets_;
303 
309  Record* records_;
310 
312  ErrorCode alloc_record(RecordIndex* out) ALWAYS_INLINE;
314  void on_memory_set();
315 
317  inline static uint16_t extract_bucket(HashValue hash) ALWAYS_INLINE {
318  return hash & 0xFFFFU; // so far the lowest 16 bits.
319  }
320 
322  struct SearchResult {
323  SearchResult(RecordIndex found, RecordIndex tail) : found_(found), tail_(tail) {}
325  RecordIndex found_;
327  RecordIndex tail_;
328  };
329  SearchResult search_bucket(
330  const void* key,
331  uint16_t key_length,
332  HashValue hash) const ALWAYS_INLINE;
333 };
334 
335 } // namespace hash
336 } // namespace storage
337 } // namespace foedus
338 #endif // FOEDUS_STORAGE_HASH_HASH_TMPBIN_HPP_
T align8(T value)
8-alignment.
Represents one record in our key-value store.
Definition: record.hpp:33
ErrorCode create_memory(uint16_t numa_node, uint64_t initial_size=kDefaultInitialSize)
Allocates the memory to use by this object.
Definition: hash_tmpbin.cpp:36
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
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
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.
void set_all(xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash, const void *payload, uint16_t payload_length) __attribute__((always_inline))
Definition: hash_tmpbin.hpp:97
void steal_memory(memory::AlignedMemory *provider)
This is a special version of create_memory() where this object steals the memory ownership from the r...
Definition: hash_tmpbin.cpp:55
char data_[kPageSize-32]
key and payload, like the log entry, key part is 8-byte aligned.
Definition: hash_tmpbin.hpp:89
An in-memory single-threaded data structure to compose tuples in a hash bin.
Definition: hash_tmpbin.hpp:54
Persistent status part of Transaction ID.
Definition: xct_id.hpp:955
friend std::ostream & operator<<(std::ostream &o, const HashTmpBin &v)
void clean_quick()
This version selectively clears buckets_ by seeing individual records.
Definition: hash_tmpbin.cpp:81
HashTmpBin()
Constructor doesn't do any initialization.
Definition: hash_tmpbin.cpp:32
Let's be super generous, assuming that we are reusing memories.
Definition: hash_tmpbin.hpp:63
Independent utility methods/classes for hashination, or hash functions.
void overwrite_payload(const void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
RecordIndex get_records_consumed() const
Definitions of IDs in this package and a few related constant values.
char * get_payload() __attribute__((always_inline))
Definition: hash_tmpbin.hpp:92
#define CXX11_FINAL
Used in public headers in place of "final" of C++11.
Definition: cxx11.hpp:131
This is a per-bin data structure.
Definition: hash_tmpbin.hpp:61
char * get_key() __attribute__((always_inline))
Definition: hash_tmpbin.hpp:91
uint32_t get_physical_record_count() const
ErrorCode delete_record(xct::XctId xct_id, const void *key, uint16_t key_length, HashValue hash)
Logically deletes a record of the given key.
Record * get_record(RecordIndex index) const
void set_payload(const void *payload, uint16_t payload_length) __attribute__((always_inline))
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.
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.
void give_memory(memory::AlignedMemory *recipient)
This is a special version of release_memory() where this object moves the memory ownership to the rec...
Definition: hash_tmpbin.cpp:64
Represents one memory block aligned to actual OS/hardware pages.
RecordIndex next_
constitutes a singly-linked list in each bucket
Definition: hash_tmpbin.hpp:86
RecordIndex get_records_capacity() const
Represents a record with a unique key.
Definition: hash_tmpbin.hpp:78
void release_memory()
Destructor automatically releases everything, but you can use this to do it earlier.
Definition: hash_tmpbin.cpp:49
RecordIndex get_first_record() const
RecordIndex get_bucket_head(uint32_t bucket) const
Record * get_record_next(const HashTmpBin *enclosure) const __attribute__((always_inline))
Definition: hash_tmpbin.hpp:93
#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
Definitions of IDs in this package and a few related constant values.
#define ALWAYS_INLINE
A function suffix to hint that the function should always be inlined.
Definition: compiler.hpp:106
const uint16_t kPageSize
A constant defining the page size (in bytes) of both snapshot pages and volatile pages.
Definition: storage_id.hpp:45
ErrorCode
Enum of error codes defined in error_code.xmacro.
Definition: error_code.hpp:85
Forward declarations of classes in hash storage package.
uint64_t HashValue
Represents a full 64-bit hash value calculated from a key.
Definition: hash_id.hpp:129