libfoedus-core
FOEDUS Core Library
hash_page_debug.cpp
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  */
19 
20 #include <ostream>
21 #include <string>
22 
26 
27 namespace foedus {
28 namespace storage {
29 namespace hash {
30 
31 std::ostream& operator<<(std::ostream& o, const HashIntermediatePage& v) {
32  o << "<HashIntermediatePage>";
33  o << std::endl << " <vaddr>" << assorted::Hex(reinterpret_cast<uintptr_t>(&v), 16) << "</vaddr>";
34  o << std::endl << " " << v.header();
35  o << std::endl << " <level>" << static_cast<int>(v.get_level()) << "</level>";
36  o << std::endl << " " << v.get_bin_range();
37  HashBin total_begin = v.get_bin_range().begin_;
38  HashBin interval = kHashMaxBins[v.get_level()];
39  for (uint16_t i = 0; i < kHashIntermediatePageFanout; ++i) {
40  DualPagePointer pointer = v.get_pointer(i);
41  if (pointer.is_both_null()) {
42  continue;
43  }
44  o << std::endl << " <Pointer index=\"" << static_cast<int>(i)
45  << "\" bin_begin=\"" << (total_begin + i * interval)
46  << "\">" << pointer << "</Pointer>";
47  }
48  o << "</HashIntermediatePage>";
49  return o;
50 }
51 
52 std::ostream& operator<<(std::ostream& o, const HashDataPage& v) {
53  o << "<HashDataPage>";
54  o << std::endl << " <vaddr>" << assorted::Hex(reinterpret_cast<uintptr_t>(&v), 16) << "</vaddr>";
55  o << std::endl << v.header();
56  o << std::endl << " <bin>" << assorted::Hex(v.get_bin()) << "</bin>";
57  uint16_t records = v.get_record_count();
58  o << std::endl << " <record_count>" << records << "</record_count>";
59  o << std::endl << " <next_page>" << v.next_page() << "</next_page>";
60  o << std::endl << " <records>";
61  for (DataPageSlotIndex i = 0; i < records; ++i) {
62  const HashDataPage::Slot* slot = v.get_slot_address(i);
63  o << std::endl << " <record index=\"" << i
64  << "\" hash=\"" << assorted::Hex(slot->hash_, 16)
65  << "\" physical_record_len=\"" << slot->physical_record_length_
66  << "\" key_length_=\"" << slot->key_length_
67  << "\" offset=\"" << slot->offset_
68  << "\" payload_len=\"" << slot->payload_length_
69  << "\">";
70  const char* data = v.record_from_offset(slot->offset_);
71  std::string key(data, slot->key_length_);
72  o << "<key>" << assorted::HexString(key) << "</key>";
73  if (slot->payload_length_ > 0) {
74  std::string payload(data + slot->get_aligned_key_length(), slot->payload_length_);
75  o << "<payload>" << assorted::HexString(payload) << "</payload>";
76  }
78  o << fingerprint;
79  o << slot->tid_;
80  o << "</record>";
81  }
82  o << std::endl << " </records>";
83  o << std::endl << " <BloomFilter>" << v.bloom_filter_ << "</BloomFilter>";
84  o << "</HashDataPage>";
85  return o;
86 }
87 
88 
90  const uint8_t bin_shifts = get_bin_shifts();
91  uint8_t records = get_record_count();
92 
93  if (header_.snapshot_) {
94  ASSERT_ND(next_page().volatile_pointer_.is_null());
95  } else {
96  ASSERT_ND(next_page().snapshot_pointer_ == 0);
97  }
98 
99  DataPageBloomFilter correct_filter;
100  correct_filter.clear();
101  for (DataPageSlotIndex i = 0; i < records; ++i) {
102  const HashDataPage::Slot* slot = get_slot_address(i);
103  if (i > 0) {
104  const HashDataPage::Slot* pre = get_slot_address(i - 1);
105  ASSERT_ND(slot->offset_ == pre->offset_ + pre->physical_record_length_);
106  }
108  ASSERT_ND(slot->hash_ == hash);
109  HashBin bin = hash >> bin_shifts;
110  ASSERT_ND(bin_ == bin);
111 
112  correct_filter.add(DataPageBloomFilter::extract_fingerprint(slot->hash_));
114  >= slot->get_aligned_key_length() + slot->payload_length_);
115  uint16_t end_offset = slot->offset_ + slot->physical_record_length_;
116  ASSERT_ND(end_offset + records * sizeof(Slot) <= (kPageSize - kHashDataPageHeaderSize));
117  }
118 
119  for (uint16_t i = 0; i < sizeof(correct_filter.values_); ++i) {
120  ASSERT_ND(correct_filter.values_[i] == bloom_filter_.values_[i]);
121  }
122 }
123 
124 
125 } // namespace hash
126 } // namespace storage
127 } // namespace foedus
Represents a pointer to another page (usually a child page).
Definition: storage_id.hpp:271
const HashBinRange & get_bin_range() const
xct::RwLockableXctId tid_
TID of the record.
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
uint16_t payload_length_
Byte length of the payload.
void assert_entries_impl() const
defined in hash_page_debug.cpp.
uint16_t key_length_
Byte length of key of the record.
HashValue hash_
Full hash of the key of the record.
const Slot * get_slot_address(DataPageSlotIndex record) const __attribute__((always_inline))
same as &get_slot(), but this is more explicit and easier to understand/maintain
Independent utility methods/classes for hashination, or hash functions.
void clear()
usually zero-cleared as part of a data page, but in case of specifically clearing this ...
HashValue hashinate(const void *key, uint16_t key_length)
Calculates hash value for general input.
std::ostream & operator<<(std::ostream &o, const HashCombo &v)
Definition: hash_combo.cpp:37
Fix-sized slot for each record, which is placed at the end of data region.
HashBin begin_
Inclusive beginning of the range.
Definition: hash_id.hpp:191
uint16_t DataPageSlotIndex
Definition: hash_id.hpp:196
Equivalent to std::hex in case the stream doesn't support it.
uint16_t physical_record_length_
Byte count this record occupies.
uint8_t values_[kHashDataPageBloomFilterBytes]
Represents an intermediate page in Hashtable Storage.
static BloomFilterFingerprint extract_fingerprint(HashValue fullhash)
char * record_from_offset(uint16_t offset)
uint64_t HashBin
Represents a bin of a hash value.
Definition: hash_id.hpp:142
void add(const BloomFilterFingerprint &fingerprint) __attribute__((always_inline))
Adds the fingerprint to this bloom filter.
Represents an individual data page in Hashtable Storage.
const DualPagePointer & next_page() const __attribute__((always_inline))
A fingerprint for bloom filter in each HashDataPage.
Convenient way of writing hex integers to stream.
To quickly check whether a HashDataPage might contain a specific hash value, we maintain a non-counti...
const uint16_t kHashDataPageHeaderSize
Byte size of header in data page of hash storage.
Definition: hash_id.hpp:110
const uint8_t kHashIntermediatePageFanout
Number of pointers in an intermediate page of hash storage.
Definition: hash_id.hpp:49
const uint64_t kHashMaxBins[]
kHashTotalBins[n] gives the maximum number of hash bins n-level hash can hold.
Definition: hash_id.hpp:74
uint16_t get_record_count() const __attribute__((always_inline))
bool snapshot_
Whether this page image is of a snapshot page.
Definition: page.hpp:211
#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.
DualPagePointer & get_pointer(uint16_t index)
const uint16_t kPageSize
A constant defining the page size (in bytes) of both snapshot pages and volatile pages.
Definition: storage_id.hpp:45
uint16_t offset_
Byte offset in data_ where this record starts.
uint64_t HashValue
Represents a full 64-bit hash value calculated from a key.
Definition: hash_id.hpp:129