libfoedus-core
FOEDUS Core Library
foedus::storage::masstree Namespace Reference

Masstree Storage, 64-bit B-tries with internal B-trees. More...

Detailed Description

Masstree Storage, 64-bit B-tries with internal B-trees.

Although the package name says masstree [YANDONG12], we call our implementation Master-Tree. There are a few differences from the original Masstree.

Foster-Twin

See our paper (lame, yes).

Remainder vs Remaining Key

Througout our code, we always use the word remainder rather than remaining-key. In [YANDONG12] and [TU13], the word remaining-key meant the leftover of the entire key after removing the common prefixes in previous B-trie layers. For example, key "abcd" has remaining key "abcd" in layer-0. key "abcd12345678" has remaining keys "abcd12345678" in layer-0 and "5678" in layer-1. When the length of remaining-key is more than 8-bytes, the page also stores suffix, which is the key part after the slice in the layer. For example, "abcd12345678" stores "5678" as suffix in layer-0 while no suffix in layer-1.

Up to here, there is no difference between remainder and remaining-key. Actually, in most cases they are exactly the same.

They differ only when a record points to next layer. In the original papers/codes, the length of remaining-key is set to be 255 when the record now points to next layer, and they also overwrite the area to store suffix with next-page pointer.

In Master-Tree, we always keep the remainder even when now it points to the next layer. This simplifies many concurrency control issues, especially our foster-twin tracking algorithm. Therefore, we never change the length of remainder. It's an immutable property of the record. Instead, we have an additional mutable boolean flag "next_layer" in TID. Whether the next_layer flag is ON or OFF, all threads are safe to access the remainder. The commit protocol checks the flag and aborts if it's unexpectedly ON.

This is just a subtle difference, but allthemore subtle, it's confusing! Hence, we use a different word, remainder. Below we summarize the differences:

.Remaining Key (Mass-Tree)Remainder (Master-Tree)
Length Full key length - layer*8 if not next-layer, 255 if it's now next-layer. Full key length - layer*8 always. Keeps the original remainder length.
Suffix stored at The beginning of data region if not next-layer, overwritten if it's now next-layer. The beginning of data region always. Keeps the original remainder.
Length 0xFFFF means The record is now next-layer, so the record has no suffix-region. HOWEVER, concurrent threads must be careful because it was not 0xFFFF before. The record was initially next-layer as of creation, so the record has no suffix-region. Such a record is never moved. A record that later turned to be next-layer doesn't use this value.

References

  • [YANDONG12] Yandong Mao, Eddie Kohler, and Robert Tappan Morris. "Cache craftiness for fast multicore key-value storage.", EuroSys, 2012.
  • [TU13] Stephen Tu, Wenting Zheng, Eddie Kohler, Barbara Liskov, and Samuel Madden. "Speedy transactions in multicore in-memory databases.", SOSP, 2013.

Classes

struct  Adopt
 A system transaction to adopt foster twins into an intermediate page. More...
 
struct  GrowFirstLayerRoot
 A system transaction to grow a first-layer root. More...
 
struct  GrowNonFirstLayerRoot
 A system transaction to grow a second- or depper-layer root. More...
 
struct  HighFence
 Used only for debugging as this is not space efficient. More...
 
class  MasstreeBorderPage
 Represents one border page in Masstree Storage. More...
 
struct  MasstreeCommonLogType
 A base class for MasstreeInsertLogType/MasstreeDeleteLogType/MasstreeOverwriteLogType. More...
 
class  MasstreeComposeContext
 MasstreeComposer's compose() implementation separated from the class itself. More...
 
class  MasstreeComposer
 Composer for an masstree storage. More...
 
struct  MasstreeCreateLogType
 Log type of CREATE MASSTREE STORAGE operation. More...
 
class  MasstreeCursor
 Represents a cursor object for Masstree storage. More...
 
struct  MasstreeDeleteLogType
 Log type of masstree-storage's delete operation. More...
 
struct  MasstreeInsertLogType
 Log type of masstree-storage's insert operation. More...
 
class  MasstreeIntermediatePage
 Represents one intermediate page in Masstree Storage. More...
 
struct  MasstreeIntermediatePointerIterator
 Handy iterator for MasstreeIntermediate. More...
 
struct  MasstreeMetadata
 Metadata of a masstree storage. More...
 
struct  MasstreeMetadataSerializer
 
struct  MasstreeOverwriteLogType
 Log type of masstree-storage's overwrite operation. More...
 
class  MasstreePage
 Common base of MasstreeIntermediatePage and MasstreeBorderPage. More...
 
class  MasstreePartitioner
 Partitioner for a masstree storage. More...
 
struct  MasstreePartitionerData
 Dynamic information of one partitioner. More...
 
class  MasstreeStorage
 Represents a Masstree storage. More...
 
struct  MasstreeStorageControlBlock
 Shared data of this storage type. More...
 
class  MasstreeStoragePimpl
 Pimpl object of MasstreeStorage. More...
 
struct  MasstreeUpdateLogType
 Log type of masstree-storage's update operation. More...
 
struct  OwnerSamples
 Number of vol pages in each node sampled per pointer in the root page. More...
 
struct  RecordLocation
 return value of MasstreeStoragePimpl::locate_record()/reserve_record(). More...
 
struct  ReserveRecords
 A system transaction to reserve a physical record(s) in a border page. More...
 
struct  SortEntry
 Unlike array's sort entry, we don't always use this because keys are arbitrary lengthes. More...
 
struct  SplitBorder
 A system transaction to split a border page in Master-Tree. More...
 
struct  SplitIntermediate
 A system transaction to split an intermediate page in Master-Tree. More...
 

Typedefs

typedef uint8_t Layer
 Represents the depth of a B-trie layer. More...
 
typedef uint8_t InLayerLevel
 Represents the depth of a B-tree node in a B-trie layer. More...
 
typedef uint16_t KeyLength
 Represents a byte-length of a key in this package. More...
 
typedef uint16_t PayloadLength
 Represents a byte-length of a payload in this package. More...
 
typedef uint16_t DataOffset
 Byte-offset in a page. More...
 
typedef uint16_t SlotIndex
 Index of a record in a (border) page. More...
 
typedef uint64_t KeySlice
 Each key slice is an 8-byte integer. More...
 

Functions

template<typename T >
KeySlice normalize_primitive (T value)
 Order-preserving normalization for primitive key types. More...
 
template<typename T >
denormalize_primitive (KeySlice value)
 Opposite of normalize_primitive(). More...
 
KeySlice normalize_be_bytes_full_aligned (const void *be_bytes)
 Convert an aligned big-endian byte array of at least 8-bytes-length to KeySlice. More...
 
KeySlice normalize_be_bytes_full (const void *be_bytes)
 Convert a big-endian byte array of at least 8-bytes-length to KeySlice. More...
 
KeySlice normalize_be_bytes_fragment (const void *be_bytes, uint32_t length)
 Convert a big-endian byte array of given length to KeySlice. More...
 
KeySlice slice_key (const void *be_bytes, KeyLength slice_length)
 Extract a part of a big-endian byte array of given length as KeySlice. More...
 
KeySlice slice_layer (const void *be_bytes, KeyLength key_length, Layer current_layer)
 Extract a part of a big-endian byte array of given length as KeySlice. More...
 
uint16_t count_common_slices (const void *left, const void *right, uint16_t max_slices)
 Returns the number of 8-byte slices that the two strings share as prefix. More...
 
bool is_key_aligned_and_zero_padded (const char *key, KeyLength key_length)
 Returns if the given key is 8-bytes aligned and also zero-padded to 8-bytes for easier slicing (which most of our code does). More...
 
uint8_t extract_page_layer (const void *in_page_pointer)
 Retrieve masstree layer information from the header of the page that contains the pointer. More...
 
KeyLength calculate_suffix_length (KeyLength remainder_length) __attribute__((always_inline))
 
KeyLength calculate_suffix_length_aligned (KeyLength remainder_length) __attribute__((always_inline))
 
void _dummy_static_size_check__COUNTER__ ()
 
int compare_keys (const char *left, uint16_t left_length, const char *right, uint16_t right_length)
 Local utility functions. More...
 
const MasstreeCommonLogTyperesolve_log (const snapshot::LogBuffer &log_buffer, snapshot::BufferPosition pos)
 
void fill_payload_padded (char *destination, const char *source, PayloadLength count)
 
MasstreeBorderPageas_border (MasstreePage *page)
 
MasstreeIntermediatePageas_intermediate (MasstreePage *page)
 
bool from_this_snapshot (SnapshotPagePointer pointer, const Composer::ConstructRootArguments &args)
 
std::ostream & operator<< (std::ostream &o, const MasstreeComposeContext::PathLevel &v)
 
void copy_input_key (const char *input_key, KeyLength length, char *buffer, KeySlice *slice_buffer)
 
void grow_case_a_common (thread::Thread *context, DualPagePointer *pointer, MasstreePage *cur_root)
 
ErrorCode grow_case_b_common (thread::Thread *context, DualPagePointer *pointer, MasstreePage *cur_root)
 
std::ostream & operator<< (std::ostream &o, const MasstreeCreateLogType &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeInsertLogType &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeDeleteLogType &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeUpdateLogType &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeOverwriteLogType &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeMetadata &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreePage &v)
 
void describe_masstree_page_common (std::ostream *o_ptr, const MasstreePage &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeIntermediatePage &v)
 
std::ostream & operator<< (std::ostream &o, const MasstreeBorderPage &v)
 
void release_parallel (Engine *engine, VolatilePagePointer pointer)
 
void design_partition_first_parallel_recurse (const memory::GlobalVolatilePageResolver &resolver, const MasstreePage *page, uint32_t subtree_id, OwnerSamples *result, assorted::UniformRandom *unirand)
 
void design_partition_first_parallel (Engine *engine, VolatilePagePointer subtree, uint32_t subtree_id, OwnerSamples *result)
 
std::ostream & operator<< (std::ostream &o, const OwnerSamples &v)
 
void retrieve_positions (uint32_t logs_count, const SortEntry *entries, snapshot::BufferPosition *out)
 subroutine of sort_batch_8bytes More...
 
void prepare_sort_entries (const Partitioner::SortBatchArguments &args, SortEntry *entries)
 subroutine of sort_batch_8bytes More...
 
std::ostream & operator<< (std::ostream &o, const MasstreePartitioner &v)
 
xct::XctId get_initial_xid ()
 
MasstreeBorderPageallocate_new_border_page (thread::Thread *context)
 
std::ostream & operator<< (std::ostream &o, const MasstreeStorage &v)
 
PayloadLength adjust_payload_hint (PayloadLength payload_count, PayloadLength physical_payload_hint)
 
uint32_t count_children_approximate (const MasstreeIntermediatePage *page)
 
ErrorStack verify_page_basic (thread::Thread *context, MasstreePage *page, PageType page_type, KeySlice low_fence, HighFence high_fence)
 

Variables

const Layer kMaxLayer = 63U
 Maximum value for Layer. More...
 
const InLayerLevel kMaxSaneInLayerLevel = 15U
 If InLayerLevel exceeds this value, there must be something wrong. More...
 
const KeyLength kMaxKeyLength = 1024U
 Max length of a key. More...
 
const KeyLength kInitiallyNextLayer = 0xFFFFU
 A special key length value that denotes the record in a border page was initially a next-layer pointer, thus the record has no suffix region. More...
 
const PayloadLength kMaxPayloadLength = 1024U
 Max length of a payload. More...
 
const uint64_t kSliceLen = sizeof(KeySlice)
 Shorthand for sizeof(KeySlice). More...
 
const KeySlice kInfimumSlice = 0
 
const KeySlice kSupremumSlice = 0xFFFFFFFFFFFFFFFFULL
 
const uint32_t kCommonPageHeaderSize = 80U
 Size of the base page class (MasstreePage), which is the common header for intermediate and border pages placed at the beginning. More...
 
const uint32_t kBorderPageAdditionalHeaderSize = 8U
 Misc header attributes specific to MasstreeBorderPage placed after the common header. More...
 
const uint32_t kBorderPageSlotSize = 32U
 Byte size of one slot in MasstreeBorderPage excluding slice information. More...
 
const SlotIndex kBorderPageMaxSlots
 Maximum number of slots in one MasstreeBorderPage. More...
 
const uint32_t kBorderPageDataPartSize
 Byte size of the record data part (data_) in MasstreeBorderPage. More...
 
const DataOffset kBorderPageDataPartOffset
 Offset of data_ member in MasstreeBorderPage. More...
 
const uint16_t kMaxIntermediateSeparators = 9U
 Max number of separators stored in the first level of intermediate pages. More...
 
const uint16_t kMaxIntermediateMiniSeparators = 15U
 Max number of separators stored in the second level of intermediate pages. More...
 
const uint32_t kMaxIntermediatePointers = (kMaxIntermediateSeparators + 1U) * (kMaxIntermediateMiniSeparators + 1U)
 Max number of pointers (if completely filled) stored in an intermediate pages. More...
 
constexpr uint32_t kIntermediateAlmostFull = kMaxIntermediatePointers * 9U / 10U
 

Function Documentation

void foedus::storage::masstree::_dummy_static_size_check__COUNTER__ ( )
inline

Definition at line 1733 of file masstree_page_impl.hpp.

PayloadLength foedus::storage::masstree::adjust_payload_hint ( PayloadLength  payload_count,
PayloadLength  physical_payload_hint 
)

Definition at line 233 of file masstree_storage.cpp.

References foedus::assorted::align8(), ASSERT_ND, and kMaxPayloadLength.

Referenced by foedus::storage::masstree::MasstreeStorage::insert_record(), foedus::storage::masstree::MasstreeStorage::insert_record_normalized(), foedus::storage::masstree::MasstreeStorage::upsert_record(), and foedus::storage::masstree::MasstreeStorage::upsert_record_normalized().

235  {
236  ASSERT_ND(physical_payload_hint >= payload_count); // if not, most likely misuse.
237  if (physical_payload_hint < payload_count) {
238  physical_payload_hint = payload_count;
239  }
240  if (physical_payload_hint > kMaxPayloadLength) {
241  physical_payload_hint = kMaxPayloadLength;
242  }
243  physical_payload_hint = assorted::align8(physical_payload_hint);
244  return physical_payload_hint;
245 }
T align8(T value)
8-alignment.
const PayloadLength kMaxPayloadLength
Max length of a payload.
Definition: masstree_id.hpp:98
#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:

Here is the caller graph for this function:

MasstreeBorderPage* foedus::storage::masstree::allocate_new_border_page ( thread::Thread context)
inline

Definition at line 39 of file masstree_reserve_impl.cpp.

References foedus::thread::Thread::get_local_volatile_page_resolver(), foedus::thread::Thread::get_numa_node(), foedus::thread::Thread::get_thread_memory(), foedus::memory::NumaCoreMemory::grab_free_volatile_page(), foedus::storage::masstree::MasstreePage::header(), foedus::storage::PageHeader::page_id_, foedus::storage::VolatilePagePointer::set(), and foedus::storage::VolatilePagePointer::word.

Referenced by foedus::storage::masstree::ReserveRecords::run().

39  {
40  memory::NumaCoreMemory* memory = context->get_thread_memory();
41  memory::PagePoolOffset offset = memory->grab_free_volatile_page();
42  if (offset == 0) {
43  return nullptr;
44  }
45 
46  const auto &resolver = context->get_local_volatile_page_resolver();
47  MasstreeBorderPage* new_page
48  = reinterpret_cast<MasstreeBorderPage*>(resolver.resolve_offset_newpage(offset));
49  VolatilePagePointer new_page_pointer;
50  new_page_pointer.set(context->get_numa_node(), offset);
51  new_page->header().page_id_ = new_page_pointer.word;
52  return new_page;
53 }
uint32_t PagePoolOffset
Offset in PagePool that compactly represents the page address (unlike 8 bytes pointer).
Definition: memory_id.hpp:44

Here is the call graph for this function:

Here is the caller graph for this function:

MasstreeBorderPage* foedus::storage::masstree::as_border ( MasstreePage page)
inline

Definition at line 56 of file masstree_composer_impl.cpp.

References ASSERT_ND, and foedus::storage::masstree::MasstreePage::is_border().

56  {
57  ASSERT_ND(page->is_border());
58  return reinterpret_cast<MasstreeBorderPage*>(page);
59 }
#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:

MasstreeIntermediatePage* foedus::storage::masstree::as_intermediate ( MasstreePage page)
inline

Definition at line 61 of file masstree_composer_impl.cpp.

References ASSERT_ND, and foedus::storage::masstree::MasstreePage::is_border().

61  {
62  ASSERT_ND(!page->is_border());
63  return reinterpret_cast<MasstreeIntermediatePage*>(page);
64 }
#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:

KeyLength foedus::storage::masstree::calculate_suffix_length ( KeyLength  remainder_length)
inline

Definition at line 1105 of file masstree_page_impl.hpp.

References ASSERT_ND, kInitiallyNextLayer, and kMaxKeyLength.

Referenced by calculate_suffix_length_aligned(), foedus::storage::masstree::MasstreeCursor::copy_combined_key(), foedus::storage::masstree::MasstreeCursor::copy_combined_key_part(), foedus::storage::masstree::MasstreeBorderPage::Slot::get_suffix_length(), foedus::storage::masstree::MasstreeBorderPage::get_suffix_length(), foedus::storage::masstree::SplitBorder::migrate_records(), and foedus::storage::masstree::MasstreeBorderPage::reserve_record_space().

1105  {
1106  if (remainder_length == kInitiallyNextLayer) {
1107  return 0;
1108  }
1109  ASSERT_ND(remainder_length <= kMaxKeyLength);
1110  if (remainder_length >= sizeof(KeySlice)) {
1111  return remainder_length - sizeof(KeySlice);
1112  } else {
1113  return 0;
1114  }
1115 }
const KeyLength kMaxKeyLength
Max length of a key.
Definition: masstree_id.hpp:75
uint64_t KeySlice
Each key slice is an 8-byte integer.
const KeyLength kInitiallyNextLayer
A special key length value that denotes the record in a border page was initially a next-layer pointe...
Definition: masstree_id.hpp:86
#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:

KeyLength foedus::storage::masstree::calculate_suffix_length_aligned ( KeyLength  remainder_length)
inline
int foedus::storage::masstree::compare_keys ( const char *  left,
uint16_t  left_length,
const char *  right,
uint16_t  right_length 
)
inline

Local utility functions.

Used in partitioner and composer.Returns negative, 0, positive if left<right, left==right, left>right.

Definition at line 203 of file masstree_partitioner_impl.hpp.

207  {
208  uint16_t cmp_length = std::min(left_length, right_length);
209  int result = std::memcmp(left, right, cmp_length);
210  if (result != 0) {
211  return result;
212  } else if (left_length < right_length) {
213  return -1;
214  } else if (left_length > right_length) {
215  return 1;
216  } else {
217  return 0;
218  }
219 }
void foedus::storage::masstree::copy_input_key ( const char *  input_key,
KeyLength  length,
char *  buffer,
KeySlice slice_buffer 
)

Definition at line 925 of file masstree_cursor.cpp.

References ASSUME_ALIGNED, and slice_key().

Referenced by foedus::storage::masstree::MasstreeCursor::open().

925  {
926  std::memcpy(ASSUME_ALIGNED(buffer, 256), input_key, length);
927  for (Layer i = 0; i * sizeof(KeySlice) < length; ++i) {
928  slice_buffer[i] = slice_key(input_key + i * sizeof(KeySlice), length - i * sizeof(KeySlice));
929  }
930 }
uint64_t KeySlice
Each key slice is an 8-byte integer.
#define ASSUME_ALIGNED(x, y)
Wraps GCC's __builtin_assume_aligned.
Definition: compiler.hpp:111
KeySlice slice_key(const void *be_bytes, KeyLength slice_length)
Extract a part of a big-endian byte array of given length as KeySlice.
uint8_t Layer
Represents the depth of a B-trie layer.
Definition: masstree_id.hpp:42

Here is the call graph for this function:

Here is the caller graph for this function:

uint32_t foedus::storage::masstree::count_children_approximate ( const MasstreeIntermediatePage page)

Definition at line 32 of file masstree_storage_fatify.cpp.

References foedus::storage::masstree::MasstreePage::get_key_count(), foedus::storage::masstree::MasstreeIntermediatePage::get_minipage(), and foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::key_count_.

Referenced by foedus::storage::masstree::MasstreeStoragePimpl::approximate_count_root_children(), and foedus::storage::masstree::MasstreeStoragePimpl::fatify_first_root_double().

32  {
33  // this method doesn't need page-lock, but instead it might be inaccurate
34  const uint16_t key_count = page->get_key_count();
35  uint32_t current_count = 0;
36  for (uint16_t minipage_index = 0; minipage_index <= key_count; ++minipage_index) {
37  const auto& minipage = page->get_minipage(minipage_index);
38  current_count += minipage.key_count_ + 1;
39  }
40  return current_count;
41 }

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::masstree::describe_masstree_page_common ( std::ostream *  o_ptr,
const MasstreePage v 
)

Definition at line 39 of file masstree_page_debug.cpp.

References foedus::storage::describe_volatile_pointer(), foedus::storage::masstree::MasstreePage::get_foster_fence(), foedus::storage::masstree::MasstreePage::get_foster_major(), foedus::storage::masstree::MasstreePage::get_foster_minor(), foedus::storage::masstree::MasstreePage::get_high_fence(), foedus::storage::masstree::MasstreePage::get_low_fence(), and foedus::storage::masstree::MasstreePage::header().

Referenced by operator<<().

39  {
40  std::ostream& o = *o_ptr;
41  o << std::endl << "<addr>" << assorted::Hex(reinterpret_cast<uintptr_t>(&v), 16) << "</addr>";
42  o << std::endl << v.header();
43  o << std::endl << "<low_fence_>" << assorted::Hex(v.get_low_fence(), 16) << "</low_fence_>";
44  o << "<high_fence_>" << assorted::Hex(v.get_high_fence(), 16) << "</high_fence_>";
45  o << "<foster_fence_>" << assorted::Hex(v.get_foster_fence(), 16) << "</foster_fence_>";
46  o << std::endl << "<foster_minor>";
47  describe_volatile_pointer(&o, v.get_foster_minor());
48  o << "</foster_minor>";
49  o << std::endl << "<foster_major>";
50  describe_volatile_pointer(&o, v.get_foster_major());
51  o << "</foster_major>";
52 }
void describe_volatile_pointer(std::ostream *o, VolatilePagePointer pointer)
Definition: storage_id.cpp:44

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::masstree::design_partition_first_parallel ( Engine engine,
VolatilePagePointer  subtree,
uint32_t  subtree_id,
OwnerSamples result 
)

Definition at line 155 of file masstree_partitioner_impl.cpp.

References ASSERT_ND, design_partition_first_parallel_recurse(), foedus::debugging::StopWatch::elapsed_us(), foedus::memory::EngineMemory::get_global_volatile_page_resolver(), foedus::Engine::get_memory_manager(), foedus::memory::GlobalVolatilePageResolver::resolve_offset(), and foedus::debugging::StopWatch::stop().

159  {
160  const memory::GlobalVolatilePageResolver& resolver
161  = engine->get_memory_manager()->get_global_volatile_page_resolver();
162  ASSERT_ND(subtree_id < result->subtrees_);
163  debugging::StopWatch watch;
164  MasstreePage* page = reinterpret_cast<MasstreePage*>(resolver.resolve_offset(subtree));
165  assorted::UniformRandom unirand(subtree_id);
166  design_partition_first_parallel_recurse(resolver, page, subtree_id, result, &unirand);
167  watch.stop();
168  VLOG(0) << "Subtree-" << subtree_id << " done in " << watch.elapsed_us() << "us";
169 }
#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
void design_partition_first_parallel_recurse(const memory::GlobalVolatilePageResolver &resolver, const MasstreePage *page, uint32_t subtree_id, OwnerSamples *result, assorted::UniformRandom *unirand)

Here is the call graph for this function:

void foedus::storage::masstree::design_partition_first_parallel_recurse ( const memory::GlobalVolatilePageResolver resolver,
const MasstreePage page,
uint32_t  subtree_id,
OwnerSamples result,
assorted::UniformRandom unirand 
)

Definition at line 124 of file masstree_partitioner_impl.cpp.

References foedus::storage::masstree::MasstreePage::header(), foedus::storage::masstree::OwnerSamples::increment(), foedus::storage::masstree::MasstreePage::is_border(), foedus::storage::VolatilePagePointer::is_null(), foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::key_count_, foedus::assorted::UniformRandom::next_uint32(), foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::pointers_, foedus::memory::GlobalVolatilePageResolver::resolve_offset(), foedus::storage::PageHeader::stat_last_updater_node_, and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by design_partition_first_parallel().

129  {
130  uint32_t node = page->header().stat_last_updater_node_;
131  result->increment(node, subtree_id);
132  // we don't care foster twins. this is just for sampling.
133  if (!page->is_border()) {
134  const auto* casted = reinterpret_cast<const MasstreeIntermediatePage*>(page);
135  const uint32_t kSamplingWidth = 3; // follow this many pointers per page.
136  for (uint32_t rep = 0; rep < kSamplingWidth; ++rep) {
137  uint32_t index = unirand->next_uint32() % (casted->get_key_count() + 1U);
138  const MasstreeIntermediatePage::MiniPage& minipage = casted->get_minipage(index);
139  uint32_t index_mini = unirand->next_uint32() % (minipage.key_count_ + 1U);
140  VolatilePagePointer pointer = minipage.pointers_[index_mini].volatile_pointer_;
141  if (pointer.is_null()) {
142  // because now this page might be changing, this is possible
143  continue;
144  }
145  MasstreePage* child = reinterpret_cast<MasstreePage*>(resolver.resolve_offset(pointer));
146  design_partition_first_parallel_recurse(resolver, child, subtree_id, result, unirand);
147  }
148  } else {
149  // so far do not bother going down to next layer. the border page's owner probably
150  // represents it well. it might not, but a worst case always exists (such as just 1 page
151  // in the first layer.. in that case anyway no luck).
152  }
153 }
void design_partition_first_parallel_recurse(const memory::GlobalVolatilePageResolver &resolver, const MasstreePage *page, uint32_t subtree_id, OwnerSamples *result, assorted::UniformRandom *unirand)

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t foedus::storage::masstree::extract_page_layer ( const void *  in_page_pointer)
inline

Retrieve masstree layer information from the header of the page that contains the pointer.

We initially stored layer information in the log, but that might be incorrect when someone moves the record to next layer between log creation and record locking, so we now extract it in apply_record().

Definition at line 72 of file masstree_log_types.hpp.

References foedus::storage::Page::get_header(), foedus::storage::PageHeader::masstree_layer_, and foedus::storage::to_page().

Referenced by foedus::storage::masstree::MasstreeCommonLogType::apply_record_prepare(), and foedus::storage::masstree::MasstreeCommonLogType::equal_record_and_log_suffixes().

72  {
73  const Page* page = to_page(in_page_pointer);
74  return page->get_header().masstree_layer_;
75 }
Page * to_page(const void *address)
super-dirty way to obtain Page the address belongs to.
Definition: page.hpp:395

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::masstree::fill_payload_padded ( char *  destination,
const char *  source,
PayloadLength  count 
)
inline

Definition at line 48 of file masstree_composer_impl.cpp.

References foedus::assorted::align8(), ASSERT_ND, and is_key_aligned_and_zero_padded().

48  {
49  if (count > 0) {
51  std::memcpy(destination, source, assorted::align8(count));
52  }
53 }
T align8(T value)
8-alignment.
bool is_key_aligned_and_zero_padded(const char *key, KeyLength key_length)
Returns if the given key is 8-bytes aligned and also zero-padded to 8-bytes for easier slicing (which...
#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:

bool foedus::storage::masstree::from_this_snapshot ( SnapshotPagePointer  pointer,
const Composer::ConstructRootArguments args 
)

Definition at line 102 of file masstree_composer_impl.cpp.

References ASSERT_ND, foedus::storage::extract_snapshot_id_from_snapshot_pointer(), foedus::snapshot::SnapshotWriter::get_snapshot_id(), foedus::snapshot::kNullSnapshotId, and foedus::storage::Composer::ConstructRootArguments::snapshot_writer_.

Referenced by foedus::storage::masstree::MasstreeComposer::construct_root().

102  {
103  if (pointer == 0) {
104  return false;
105  }
107  ASSERT_ND(snapshot_id != snapshot::kNullSnapshotId);
108  return snapshot_id == args.snapshot_writer_->get_snapshot_id();
109 }
uint16_t extract_snapshot_id_from_snapshot_pointer(SnapshotPagePointer pointer)
Definition: storage_id.hpp:98
uint16_t SnapshotId
Unique ID of Snapshot.
Definition: snapshot_id.hpp:43
const SnapshotId kNullSnapshotId
Definition: snapshot_id.hpp:45
#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:

Here is the caller graph for this function:

xct::XctId foedus::storage::masstree::get_initial_xid ( )
inline

Definition at line 31 of file masstree_reserve_impl.cpp.

References foedus::Epoch::kEpochInitialCurrent, and foedus::xct::XctId::set().

Referenced by foedus::storage::masstree::ReserveRecords::run().

31  {
32  xct::XctId initial_id;
33  initial_id.set(
34  Epoch::kEpochInitialCurrent, // TODO(Hideaki) this should be something else
35  0);
36  return initial_id;
37 }

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::masstree::grow_case_a_common ( thread::Thread context,
DualPagePointer pointer,
MasstreePage cur_root 
)

Definition at line 36 of file masstree_grow_impl.cpp.

References ASSERT_ND, foedus::thread::Thread::collect_retired_volatile_page(), foedus::storage::masstree::MasstreePage::get_foster_fence(), foedus::storage::masstree::MasstreePage::get_foster_major(), foedus::storage::masstree::MasstreePage::get_foster_minor(), foedus::thread::Thread::get_global_volatile_page_resolver(), foedus::storage::masstree::MasstreePage::get_high_fence(), foedus::storage::masstree::MasstreePage::get_low_fence(), foedus::storage::masstree::MasstreePage::get_version_address(), foedus::storage::masstree::MasstreePage::get_volatile_page_id(), foedus::storage::masstree::MasstreePage::header(), foedus::storage::masstree::MasstreePage::is_empty_range(), foedus::storage::masstree::MasstreePage::is_locked(), foedus::storage::PageVersionStatus::kRetiredBit, foedus::storage::masstree::MasstreePage::set_retired(), foedus::storage::PageHeader::snapshot_, foedus::storage::PageVersionStatus::status_, foedus::storage::PageVersion::status_, and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by foedus::storage::masstree::GrowFirstLayerRoot::run(), and foedus::storage::masstree::GrowNonFirstLayerRoot::run().

39  {
40  ASSERT_ND(cur_root->is_locked());
41  const auto& resolver = context->get_global_volatile_page_resolver();
42  MasstreePage* minor
43  = reinterpret_cast<MasstreePage*>(resolver.resolve_offset(cur_root->get_foster_minor()));
44  MasstreePage* major
45  = reinterpret_cast<MasstreePage*>(resolver.resolve_offset(cur_root->get_foster_major()));
46 
47  ASSERT_ND(minor->get_low_fence() == cur_root->get_low_fence());
48  ASSERT_ND(minor->get_high_fence() == cur_root->get_foster_fence());
49  ASSERT_ND(major->get_low_fence() == cur_root->get_foster_fence());
50  ASSERT_ND(major->get_high_fence() == cur_root->get_high_fence());
51  ASSERT_ND(!minor->header().snapshot_);
52  ASSERT_ND(!major->header().snapshot_);
53  ASSERT_ND(minor->is_empty_range() != major->is_empty_range());
54 
55  VolatilePagePointer nonempty_pointer;
56  MasstreePage* empty_child;
57  if (minor->is_empty_range()) {
58  empty_child = minor;
59  nonempty_pointer = cur_root->get_foster_major();
60  } else {
61  empty_child = major;
62  nonempty_pointer = cur_root->get_foster_minor();
63  }
64 
65  // snapshot pointer does NOT have to be reset. This is still logically the same page.
66  pointer->volatile_pointer_ = nonempty_pointer;
67 
68  // Same as Adopt::adopt_case_a()
69  ASSERT_ND(!empty_child->is_locked());
70  empty_child->get_version_address()->status_.status_ |= PageVersionStatus::kRetiredBit;
71  context->collect_retired_volatile_page(empty_child->get_volatile_page_id());
72  cur_root->set_retired();
73  context->collect_retired_volatile_page(cur_root->get_volatile_page_id());
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:

Here is the caller graph for this function:

ErrorCode foedus::storage::masstree::grow_case_b_common ( thread::Thread context,
DualPagePointer pointer,
MasstreePage cur_root 
)

Definition at line 76 of file masstree_grow_impl.cpp.

References ASSERT_ND, foedus::thread::Thread::collect_retired_volatile_page(), foedus::storage::masstree::MasstreePage::get_btree_level(), foedus::storage::masstree::MasstreePage::get_foster_fence(), foedus::storage::masstree::MasstreePage::get_foster_major(), foedus::storage::masstree::MasstreePage::get_foster_minor(), foedus::thread::Thread::get_global_volatile_page_resolver(), foedus::storage::masstree::MasstreePage::get_layer(), foedus::storage::masstree::MasstreeIntermediatePage::get_minipage(), foedus::thread::Thread::get_thread_memory(), foedus::storage::masstree::MasstreePage::get_volatile_page_id(), foedus::memory::NumaCoreMemory::grab_free_volatile_page_pointer(), foedus::storage::masstree::MasstreePage::header(), foedus::storage::masstree::MasstreeIntermediatePage::initialize_volatile_page(), foedus::storage::masstree::MasstreePage::is_locked(), foedus::storage::VolatilePagePointer::is_null(), foedus::kErrorCodeMemoryNoFreePages, foedus::kErrorCodeOk, foedus::storage::PageHeader::key_count_, foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::key_count_, kInfimumSlice, kSupremumSlice, foedus::assorted::memory_fence_release(), foedus::storage::masstree::MasstreePage::set_retired(), foedus::storage::PageHeader::storage_id_, and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by foedus::storage::masstree::GrowFirstLayerRoot::run(), and foedus::storage::masstree::GrowNonFirstLayerRoot::run().

79  {
80  ASSERT_ND(cur_root->is_locked());
81  const auto& resolver = context->get_global_volatile_page_resolver();
82 
83  // In this case, we create a new intermediate page.
84  memory::NumaCoreMemory* memory = context->get_thread_memory();
85  VolatilePagePointer new_pointer = memory->grab_free_volatile_page_pointer();
86  if (new_pointer.is_null()) {
88  }
89  MasstreeIntermediatePage* new_root = reinterpret_cast<MasstreeIntermediatePage*>(
90  resolver.resolve_offset_newpage(new_pointer));
91  new_root->initialize_volatile_page(
92  cur_root->header().storage_id_,
93  new_pointer,
94  cur_root->get_layer(),
95  cur_root->get_btree_level() + 1U,
96  kInfimumSlice, // infimum slice
97  kSupremumSlice); // high-fence is supremum
98 
99  new_root->header().key_count_ = 0;
100  auto& mini_page = new_root->get_minipage(0);
101  mini_page.key_count_ = 1;
102  mini_page.pointers_[0].snapshot_pointer_ = 0;
103  mini_page.pointers_[0].volatile_pointer_ = cur_root->get_foster_minor();
104  mini_page.pointers_[1].snapshot_pointer_ = 0;
105  mini_page.pointers_[1].volatile_pointer_ = cur_root->get_foster_major();
106  mini_page.separators_[0] = cur_root->get_foster_fence();
107 
108  // Let's install a pointer to the new root page
109  assorted::memory_fence_release(); // must be after populating the new_root.
110  // snapshot pointer does NOT have to be reset. This is still logically the same page.
111  pointer->volatile_pointer_ = new_pointer;
112 
113  // the old root page is now retired
114  cur_root->set_retired();
115  context->collect_retired_volatile_page(cur_root->get_volatile_page_id());
116  return kErrorCodeOk;
117 }
const KeySlice kInfimumSlice
0 means no-error.
Definition: error_code.hpp:87
0x0301 : "MEMORY : Not enough free volatile pages. Check the config of MemoryOptions" ...
Definition: error_code.hpp:142
const KeySlice kSupremumSlice
#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
void memory_fence_release()
Equivalent to std::atomic_thread_fence(std::memory_order_release).

Here is the call graph for this function:

Here is the caller graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreePage v 
)

Definition at line 30 of file masstree_page_debug.cpp.

References foedus::storage::masstree::MasstreePage::is_border().

30  {
31  if (v.is_border()) {
32  o << reinterpret_cast<const MasstreeBorderPage&>(v);
33  } else {
34  o << reinterpret_cast<const MasstreeIntermediatePage&>(v);
35  }
36  return o;
37 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeMetadata v 
)

Definition at line 34 of file masstree_metadata.cpp.

34  {
35  o << MasstreeMetadataSerializer(const_cast<MasstreeMetadata*>(&v));
36  return o;
37 }
std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeCreateLogType v 
)

Definition at line 50 of file masstree_log_types.cpp.

References foedus::storage::masstree::MasstreeCreateLogType::metadata_.

50  {
51  o << "<MasstreeCreateLog>" << v.metadata_ << "</MasstreeCreateLog>";
52  return o;
53 }
std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeIntermediatePage v 
)

Definition at line 54 of file masstree_page_debug.cpp.

References describe_masstree_page_common(), foedus::storage::masstree::MasstreePage::get_key_count(), foedus::storage::masstree::MasstreePage::get_low_fence(), foedus::storage::masstree::MasstreeIntermediatePage::get_minipage(), foedus::storage::masstree::MasstreeIntermediatePage::get_separator(), foedus::storage::masstree::MasstreePage::is_empty_range(), foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::key_count_, foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::pointers_, and foedus::storage::masstree::MasstreeIntermediatePage::MiniPage::separators_.

54  {
55  o << "<MasstreeIntermediatePage>";
57  if (v.is_empty_range()) {
58  o << "<EmptyRangePage />";
59  } else {
60  for (uint16_t i = 0; i <= v.get_key_count(); ++i) {
61  const MasstreeIntermediatePage::MiniPage& minipage = v.get_minipage(i);
62  KeySlice minipage_low = i == 0 ? v.get_low_fence() : v.get_separator(i - 1);
63  o << std::endl << " <Minipage index=\"" << static_cast<int>(i)
64  << "\" low=\"" << assorted::Hex(minipage_low, 16)
65  << "\" count=\"" << static_cast<int>(minipage.key_count_)
66  << "\">";
67  for (uint16_t j = 0; j <= minipage.key_count_; ++j) {
68  o << std::endl << " <Pointer index=\"" << static_cast<int>(j)
69  << "\" low=\""
70  << assorted::Hex(j == 0 ? minipage_low : minipage.separators_[j - 1], 16)
71  << "\">" << minipage.pointers_[j] << "</Pointer>";
72  }
73  o << std::endl << " </Minipage>";
74  }
75  }
76  o << "</MasstreeIntermediatePage>";
77  return o;
78 }
void describe_masstree_page_common(std::ostream *o_ptr, const MasstreePage &v)
uint64_t KeySlice
Each key slice is an 8-byte integer.

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeInsertLogType v 
)

Definition at line 55 of file masstree_log_types.cpp.

References foedus::storage::masstree::MasstreeCommonLogType::get_key(), foedus::storage::masstree::MasstreeCommonLogType::get_payload(), foedus::storage::masstree::MasstreeCommonLogType::key_length_, and foedus::storage::masstree::MasstreeCommonLogType::payload_count_.

55  {
56  o << "<MasstreeInsertLogType>"
57  << "<key_length_>" << v.key_length_ << "</key_length_>"
58  << "<key_>" << assorted::Top(v.get_key(), v.key_length_) << "</key_>"
59  << "<payload_count_>" << v.payload_count_ << "</payload_count_>"
60  << "<payload_>" << assorted::Top(v.get_payload(), v.payload_count_) << "</payload_>"
61  << "</MasstreeInsertLogType>";
62  return o;
63 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeDeleteLogType v 
)

Definition at line 65 of file masstree_log_types.cpp.

References foedus::storage::masstree::MasstreeCommonLogType::get_key(), and foedus::storage::masstree::MasstreeCommonLogType::key_length_.

65  {
66  o << "<MasstreeDeleteLogType>"
67  << "<key_length_>" << v.key_length_ << "</key_length_>"
68  << "<key_>" << assorted::Top(v.get_key(), v.key_length_) << "</key_>"
69  << "</MasstreeDeleteLogType>";
70  return o;
71 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeStorage v 
)

Definition at line 71 of file masstree_storage.cpp.

References foedus::storage::Storage< CONTROL_BLOCK >::get_id(), and foedus::storage::Storage< CONTROL_BLOCK >::get_name().

71  {
72  o << "<MasstreeStorage>"
73  << "<id>" << v.get_id() << "</id>"
74  << "<name>" << v.get_name() << "</name>"
75  << "</MasstreeStorage>";
76  return o;
77 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeUpdateLogType v 
)

Definition at line 73 of file masstree_log_types.cpp.

References foedus::storage::masstree::MasstreeCommonLogType::get_key(), foedus::storage::masstree::MasstreeCommonLogType::get_payload(), foedus::storage::masstree::MasstreeCommonLogType::key_length_, and foedus::storage::masstree::MasstreeCommonLogType::payload_count_.

73  {
74  o << "<MasstreeUpdateLogType>"
75  << "<key_length_>" << v.key_length_ << "</key_length_>"
76  << "<key_>" << assorted::Top(v.get_key(), v.key_length_) << "</key_>"
77  << "<payload_count_>" << v.payload_count_ << "</payload_count_>"
78  << "<payload_>" << assorted::Top(v.get_payload(), v.payload_count_) << "</payload_>"
79  << "</MasstreeUpdateLogType>";
80  return o;
81 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeBorderPage v 
)

Definition at line 80 of file masstree_page_debug.cpp.

References foedus::storage::masstree::MasstreeBorderPage::SlotLengthUnion::components, describe_masstree_page_common(), foedus::storage::masstree::MasstreeBorderPage::does_point_to_layer(), foedus::storage::masstree::MasstreePage::get_key_count(), foedus::storage::masstree::MasstreeBorderPage::get_next_layer(), foedus::storage::masstree::MasstreeBorderPage::get_offset_in_bytes(), foedus::storage::masstree::MasstreeBorderPage::get_owner_id(), foedus::storage::masstree::MasstreeBorderPage::get_payload_length(), foedus::storage::masstree::MasstreeBorderPage::get_record(), foedus::storage::masstree::MasstreeBorderPage::get_record_payload(), foedus::storage::masstree::MasstreeBorderPage::get_remainder_length(), foedus::storage::masstree::MasstreeBorderPage::get_slice(), foedus::storage::masstree::MasstreeBorderPage::get_slot(), foedus::storage::masstree::MasstreeBorderPage::get_suffix_length(), foedus::storage::masstree::MasstreeBorderPage::Slot::lengthes_, and foedus::storage::masstree::MasstreeBorderPage::SlotLengthPart::physical_record_length_.

80  {
81  o << "<MasstreeBorderPage>";
83  o << "<consecutive_inserts_>" << v.consecutive_inserts_ << "</consecutive_inserts_>";
84  o << std::endl << "<records>";
85  for (uint16_t i = 0; i < v.get_key_count(); ++i) {
86  o << std::endl << " <record index=\"" << i
87  << "\" slice=\"" << assorted::Hex(v.get_slice(i), 16)
88  << "\" remainder_len=\"" << static_cast<int>(v.get_remainder_length(i))
89  << "\" offset=\"" << v.get_offset_in_bytes(i)
90  << "\" physical_record_len=\"" << v.get_slot(i)->lengthes_.components.physical_record_length_
91  << "\" payload_len=\"" << v.get_payload_length(i)
92  << "\">";
93  if (v.does_point_to_layer(i)) {
94  o << "<next_layer>" << *v.get_next_layer(i) << "</next_layer>";
95  } else {
96  if (v.get_remainder_length(i) > sizeof(KeySlice)) {
97  std::string suffix(v.get_record(i), v.get_suffix_length(i));
98  o << "<key_suffix>" << assorted::HexString(suffix) << "</key_suffix>";
99  }
100  if (v.get_payload_length(i) > 0) {
101  std::string payload(v.get_record_payload(i), v.get_payload_length(i));
102  o << "<payload>" << assorted::HexString(payload) << "</payload>";
103  }
104  }
105  o << * v.get_owner_id(i);
106  o << "</record>";
107  }
108  o << std::endl << "</records>";
109  o << "</MasstreeBorderPage>";
110  return o;
111 }
void describe_masstree_page_common(std::ostream *o_ptr, const MasstreePage &v)
uint64_t KeySlice
Each key slice is an 8-byte integer.

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeOverwriteLogType v 
)

Definition at line 83 of file masstree_log_types.cpp.

References foedus::storage::masstree::MasstreeCommonLogType::get_key(), foedus::storage::masstree::MasstreeCommonLogType::get_payload(), foedus::storage::masstree::MasstreeCommonLogType::key_length_, foedus::storage::masstree::MasstreeCommonLogType::payload_count_, and foedus::storage::masstree::MasstreeCommonLogType::payload_offset_.

83  {
84  o << "<MasstreeOverwriteLog>"
85  << "<key_length_>" << v.key_length_ << "</key_length_>"
86  << "<key_>" << assorted::Top(v.get_key(), v.key_length_) << "</key_>"
87  << "<payload_offset_>" << v.payload_offset_ << "</payload_offset_>"
88  << "<payload_count_>" << v.payload_count_ << "</payload_count_>"
89  << "<payload_>" << assorted::Top(v.get_payload(), v.payload_count_) << "</payload_>"
90  << "</MasstreeOverwriteLog>";
91  return o;
92 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const OwnerSamples v 
)

Definition at line 231 of file masstree_partitioner_impl.cpp.

References foedus::storage::masstree::OwnerSamples::at(), foedus::storage::masstree::OwnerSamples::get_assignment(), foedus::storage::masstree::OwnerSamples::nodes_, and foedus::storage::masstree::OwnerSamples::subtrees_.

231  {
232  o << "<OwnerSamples nodes=\"" << v.nodes_
233  << "\" subtrees=\"" << v.subtrees_ << "\">" << std::endl;
234  o << "<!-- legend id=\"x\" assignment=\"x\">";
235  for (uint32_t node = 0; node < v.nodes_; ++node) {
236  o << "[Node-" << node << "] ";
237  }
238  o << " -->" << std::endl;
239  for (uint32_t subtree_id = 0; subtree_id < v.subtrees_; ++subtree_id) {
240  o << " <subtree id=\"" << subtree_id
241  << "\" assignment=\"" << v.get_assignment(subtree_id) << "\">";
242  for (uint32_t node = 0; node < v.nodes_; ++node) {
243  o << assorted::Hex(v.at(node, subtree_id), 6) << " ";
244  }
245  o << "</subtree>" << std::endl;
246  }
247  o << std::endl << "</OwnerSamples>";
248  return o;
249 }

Here is the call graph for this function:

std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreePartitioner v 
)

Definition at line 503 of file masstree_partitioner_impl.cpp.

References foedus::storage::masstree::MasstreePartitionerData::low_keys_, foedus::storage::masstree::MasstreePartitionerData::partition_count_, and foedus::storage::masstree::MasstreePartitionerData::partitions_.

503  {
504  o << "<MasstreePartitioner>";
505  if (v.data_) {
506  o << "<partition_count_>" << v.data_->partition_count_ << "</partition_count_>"
507  << "<partitions>";
508  for (uint16_t i = 0; i < v.data_->partition_count_; ++i) {
509  o << std::endl << " <partition node=\"" << v.data_->partitions_[i] << "\">"
510  << assorted::Hex(v.data_->low_keys_[i], 16)
511  << "</partition>";
512  }
513  o << "</partitions>";
514  } else {
515  o << "Not yet designed";
516  }
517  o << "</MasstreePartitioner>";
518  return o;
519 }
std::ostream& foedus::storage::masstree::operator<< ( std::ostream &  o,
const MasstreeComposeContext::PathLevel v 
)

Definition at line 2851 of file masstree_composer_impl.cpp.

References foedus::storage::masstree::MasstreeComposeContext::PathLevel::head_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::high_fence_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::layer_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::low_fence_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::next_original_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::next_original_mini_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::next_original_slice_, foedus::storage::masstree::MasstreeComposeContext::PathLevel::page_count_, and foedus::storage::masstree::MasstreeComposeContext::PathLevel::tail_.

2851  {
2852  o << "<PathLevel>"
2853  << "<layer_>" << static_cast<int>(v.layer_) << "</layer_>"
2854  << "<next_original_>" << static_cast<int>(v.next_original_) << "</next_original_>"
2855  << "<next_original_mini>" << static_cast<int>(v.next_original_mini_) << "</next_original_mini>"
2856  << "<head>" << v.head_ << "</head>"
2857  << "<tail_>" << v.tail_ << "</tail_>"
2858  << "<page_count_>" << v.page_count_ << "</page_count_>"
2859  << "<low_fence_>" << assorted::Hex(v.low_fence_, 16) << "</low_fence_>"
2860  << "<high_fence_>" << assorted::Hex(v.high_fence_, 16) << "</high_fence_>"
2861  << "<next_original_slice_>"
2862  << assorted::Hex(v.next_original_slice_, 16) << "</next_original_slice_>"
2863  << "</PathLevel>";
2864  return o;
2865 }
void foedus::storage::masstree::prepare_sort_entries ( const Partitioner::SortBatchArguments args,
SortEntry entries 
)

subroutine of sort_batch_8bytes

Definition at line 444 of file masstree_partitioner_impl.cpp.

References ASSERT_ND, foedus::storage::Partitioner::SortBatchArguments::base_epoch_, foedus::xct::XctId::get_epoch(), foedus::storage::masstree::MasstreeCommonLogType::get_key(), foedus::xct::XctId::get_ordinal(), foedus::log::BaseLogType::header_, foedus::storage::masstree::MasstreeCommonLogType::key_length_, foedus::log::kLogCodeMasstreeDelete, foedus::log::kLogCodeMasstreeInsert, foedus::log::kLogCodeMasstreeOverwrite, foedus::log::kLogCodeMasstreeUpdate, foedus::storage::Partitioner::SortBatchArguments::log_buffer_, foedus::storage::Partitioner::SortBatchArguments::log_positions_, foedus::log::LogHeader::log_type_code_, foedus::storage::Partitioner::SortBatchArguments::logs_count_, normalize_be_bytes_full_aligned(), foedus::snapshot::LogBuffer::resolve(), foedus::storage::masstree::SortEntry::set(), foedus::Epoch::subtract(), and foedus::log::LogHeader::xct_id_.

444  {
445  const Epoch base_epoch = args.base_epoch_;
446  // CPU profile of partition_masstree_perf: 9-10%.
447  for (uint32_t i = 0; i < args.logs_count_; ++i) {
448  const MasstreeCommonLogType* log_entry = reinterpret_cast<const MasstreeCommonLogType*>(
449  args.log_buffer_.resolve(args.log_positions_[i]));
450  ASSERT_ND(log_entry->header_.log_type_code_ == log::kLogCodeMasstreeInsert
451  || log_entry->header_.log_type_code_ == log::kLogCodeMasstreeDelete
452  || log_entry->header_.log_type_code_ == log::kLogCodeMasstreeUpdate
453  || log_entry->header_.log_type_code_ == log::kLogCodeMasstreeOverwrite);
454  ASSERT_ND(log_entry->key_length_ == sizeof(KeySlice));
455  Epoch epoch = log_entry->header_.xct_id_.get_epoch();
456  ASSERT_ND(epoch.subtract(base_epoch) < (1U << 16));
457  uint16_t compressed_epoch = epoch.subtract(base_epoch);
458  entries[i].set(
459  normalize_be_bytes_full_aligned(log_entry->get_key()),
460  compressed_epoch,
461  log_entry->header_.xct_id_.get_ordinal(),
462  args.log_positions_[i]);
463  }
464 }
0x0033 : foedus::storage::masstree::MasstreeInsertLogType .
Definition: log_type.hpp:127
uint64_t KeySlice
Each key slice is an 8-byte integer.
0x0032 : foedus::storage::masstree::MasstreeOverwriteLogType .
Definition: log_type.hpp:126
0x0034 : foedus::storage::masstree::MasstreeDeleteLogType .
Definition: log_type.hpp:128
0x0035 : foedus::storage::masstree::MasstreeUpdateLogType .
Definition: log_type.hpp:129
#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
KeySlice normalize_be_bytes_full_aligned(const void *be_bytes)
Convert an aligned big-endian byte array of at least 8-bytes-length to KeySlice.

Here is the call graph for this function:

void foedus::storage::masstree::release_parallel ( Engine engine,
VolatilePagePointer  pointer 
)

Definition at line 178 of file masstree_page_impl.cpp.

References foedus::memory::EngineMemory::get_global_volatile_page_resolver(), foedus::Engine::get_memory_manager(), foedus::memory::PageReleaseBatch::release_all(), foedus::storage::masstree::MasstreePage::release_pages_recursive_common(), and foedus::memory::GlobalVolatilePageResolver::resolve_offset().

Referenced by foedus::storage::masstree::MasstreeIntermediatePage::release_pages_recursive_parallel().

178  {
179  const memory::GlobalVolatilePageResolver& page_resolver
180  = engine->get_memory_manager()->get_global_volatile_page_resolver();
181  MasstreePage* p = reinterpret_cast<MasstreePage*>(page_resolver.resolve_offset(pointer));
182  memory::PageReleaseBatch release_batch(engine);
183  p->release_pages_recursive_common(page_resolver, &release_batch);
184  release_batch.release_all();
185 }

Here is the call graph for this function:

Here is the caller graph for this function:

const MasstreeCommonLogType* foedus::storage::masstree::resolve_log ( const snapshot::LogBuffer log_buffer,
snapshot::BufferPosition  pos 
)
inline

Definition at line 221 of file masstree_partitioner_impl.hpp.

References ASSERT_ND, foedus::log::LogHeader::get_type(), foedus::log::BaseLogType::header_, foedus::log::kLogCodeMasstreeDelete, foedus::log::kLogCodeMasstreeInsert, foedus::log::kLogCodeMasstreeOverwrite, foedus::log::kLogCodeMasstreeUpdate, and foedus::snapshot::LogBuffer::resolve().

Referenced by foedus::storage::masstree::MasstreePartitioner::partition_batch().

223  {
224  const MasstreeCommonLogType* rec = reinterpret_cast<const MasstreeCommonLogType*>(
225  log_buffer.resolve(pos));
226  ASSERT_ND(rec->header_.get_type() == log::kLogCodeMasstreeInsert
227  || rec->header_.get_type() == log::kLogCodeMasstreeDelete
228  || rec->header_.get_type() == log::kLogCodeMasstreeUpdate
229  || rec->header_.get_type() == log::kLogCodeMasstreeOverwrite);
230  return rec;
231 }
0x0033 : foedus::storage::masstree::MasstreeInsertLogType .
Definition: log_type.hpp:127
0x0032 : foedus::storage::masstree::MasstreeOverwriteLogType .
Definition: log_type.hpp:126
0x0034 : foedus::storage::masstree::MasstreeDeleteLogType .
Definition: log_type.hpp:128
0x0035 : foedus::storage::masstree::MasstreeUpdateLogType .
Definition: log_type.hpp:129
#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:

Here is the caller graph for this function:

void foedus::storage::masstree::retrieve_positions ( uint32_t  logs_count,
const SortEntry entries,
snapshot::BufferPosition out 
)

subroutine of sort_batch_8bytes

Definition at line 432 of file masstree_partitioner_impl.cpp.

References foedus::storage::masstree::SortEntry::position_.

435  {
436  // CPU profile of partition_masstree_perf: 2-3%. (10-15% if the "index" idea is used)
437  for (uint32_t i = 0; i < logs_count; ++i) {
438  out[i] = entries[i].position_;
439  }
440 }
ErrorStack foedus::storage::masstree::verify_page_basic ( thread::Thread context,
MasstreePage page,
PageType  page_type,
KeySlice  low_fence,
HighFence  high_fence 
)

Definition at line 69 of file masstree_storage_verify.cpp.

References CHECK_AND_ASSERT, foedus::storage::masstree::MasstreePage::get_btree_level(), foedus::storage::masstree::MasstreePage::get_foster_major(), foedus::storage::masstree::MasstreePage::get_foster_minor(), foedus::storage::masstree::MasstreePage::get_high_fence(), foedus::storage::masstree::MasstreePage::get_low_fence(), foedus::storage::PageHeader::get_page_type(), foedus::storage::Page::get_page_type(), foedus::storage::masstree::MasstreePage::has_foster_child(), foedus::storage::masstree::MasstreePage::header(), foedus::storage::masstree::MasstreePage::is_border(), foedus::storage::masstree::MasstreePage::is_foster_major_null(), foedus::storage::masstree::MasstreePage::is_foster_minor_null(), foedus::storage::masstree::MasstreePage::is_high_fence_supremum(), foedus::storage::masstree::MasstreePage::is_locked(), foedus::storage::masstree::MasstreePage::is_moved(), foedus::kRetOk, foedus::thread::Thread::resolve(), foedus::storage::masstree::HighFence::slice_, foedus::storage::PageHeader::snapshot_, and foedus::storage::masstree::HighFence::supremum_.

Referenced by foedus::storage::masstree::MasstreeStoragePimpl::verify_single_thread_border(), and foedus::storage::masstree::MasstreeStoragePimpl::verify_single_thread_intermediate().

74  {
75  CHECK_AND_ASSERT(!page->is_locked());
76  CHECK_AND_ASSERT(page->header().get_page_type() == page_type);
77  CHECK_AND_ASSERT(page->is_border() || page->get_btree_level() > 0);
78  CHECK_AND_ASSERT(!page->is_border() || page->get_btree_level() == 0);
79  CHECK_AND_ASSERT(page->get_low_fence() == low_fence);
80  CHECK_AND_ASSERT(page->get_high_fence() == high_fence.slice_);
81  CHECK_AND_ASSERT(page->is_high_fence_supremum() == high_fence.supremum_);
83  (page->is_moved() && page->has_foster_child()
84  && !page->is_foster_major_null() && !page->is_foster_minor_null()) ||
85  (!page->is_moved() && !page->has_foster_child()
86  && page->is_foster_major_null() && page->is_foster_minor_null()));
87 
88  if (!page->is_foster_major_null()) {
89  CHECK_AND_ASSERT(!page->header().snapshot_);
90  CHECK_AND_ASSERT(!context->resolve(page->get_foster_major())->get_header().snapshot_);
91  CHECK_AND_ASSERT(context->resolve(page->get_foster_major())->get_header().get_page_type()
92  == page_type);
93  }
94  if (!page->is_foster_minor_null()) {
95  CHECK_AND_ASSERT(!page->header().snapshot_);
96  CHECK_AND_ASSERT(!context->resolve(page->get_foster_minor())->get_header().snapshot_);
97  CHECK_AND_ASSERT(context->resolve(page->get_foster_minor())->get_header().get_page_type()
98  == page_type);
99  }
100  return kRetOk;
101 }
#define CHECK_AND_ASSERT(x)
const ErrorStack kRetOk
Normal return value for no-error case.

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

const DataOffset foedus::storage::masstree::kBorderPageDataPartOffset
Initial value:
+ 8U
const uint32_t kCommonPageHeaderSize
Size of the base page class (MasstreePage), which is the common header for intermediate and border pa...
uint64_t KeySlice
Each key slice is an 8-byte integer.
const SlotIndex kBorderPageMaxSlots
Maximum number of slots in one MasstreeBorderPage.

Offset of data_ member in MasstreeBorderPage.

Definition at line 178 of file masstree_id.hpp.

Referenced by foedus::storage::masstree::MasstreeCommonLogType::apply_record_prepare().

constexpr uint32_t foedus::storage::masstree::kIntermediateAlmostFull = kMaxIntermediatePointers * 9U / 10U