libfoedus-core
FOEDUS Core Library
foedus::storage::masstree::MasstreeCursor::Route Struct Reference

Represents one page in the current search path from layer0-root. More...

Detailed Description

Represents one page in the current search path from layer0-root.

Either it's interior or border, this object stores some kind of a marker to note up to where we read the page so far.

Definition at line 83 of file masstree_cursor.hpp.

#include <masstree_cursor.hpp>

Collaboration diagram for foedus::storage::masstree::MasstreeCursor::Route:

Public Types

enum  MovedPageSearchStatus { kNone = 0, kMovedPageSearchedNeither = 1, kMovedPageSearchedOne = 2, kMovedPageSearchedBoth = 3 }
 

Public Member Functions

SlotIndex get_cur_original_index () const __attribute__((always_inline))
 
SlotIndex get_original_index (SlotIndex index) const __attribute__((always_inline))
 
bool is_valid_record () const __attribute__((always_inline))
 
bool was_stably_moved () const
 In almost all places of the cursor code, we check is_moved() only on the stable version so that the cursor can consistently decide whether to follow foster-twins or not. More...
 
void setup_order ()
 

Public Attributes

MasstreePagepage_
 
PageVersionStatus stable_
 version as of calculating order_. More...
 
SlotIndex index_
 index in ordered keys. More...
 
SlotIndex index_mini_
 only for interior. More...
 
SlotIndex key_count_
 same as stable_.get_key_count() More...
 
SlotIndex key_count_mini_
 only for interior. More...
 
bool snapshot_
 whether page_ is a snapshot page More...
 
Layer layer_
 Shorthand for page_->get_layer() More...
 
MovedPageSearchStatus moved_page_search_status_
 only when stable_ indicates that this page is a moved page More...
 
KeySlice latest_separator_
 Upto which separator we are done. More...
 
SlotIndex order_ [kBorderPageMaxSlots]
 only for border. More...
 

Member Enumeration Documentation

Enumerator
kNone 

This means either was_stably_moved() is false or it's intermediate page, in which case we don't neeed to follow foster twins.

If it's a border page whose was_stably_moved() returns true, the status might be one of the followings.

kMovedPageSearchedNeither 
kMovedPageSearchedOne 
kMovedPageSearchedBoth 

Definition at line 84 of file masstree_cursor.hpp.

Member Function Documentation

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::get_cur_original_index ( ) const
inline

Definition at line 147 of file masstree_cursor.hpp.

References index_.

147  {
148  return order_[index_];
149  }
SlotIndex order_[kBorderPageMaxSlots]
only for border.
SlotIndex foedus::storage::masstree::MasstreeCursor::Route::get_original_index ( SlotIndex  index) const
inline

Definition at line 150 of file masstree_cursor.hpp.

150  {
151  return order_[index];
152  }
SlotIndex order_[kBorderPageMaxSlots]
only for border.
bool foedus::storage::masstree::MasstreeCursor::Route::is_valid_record ( ) const
inline

Definition at line 153 of file masstree_cursor.hpp.

References key_count_.

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

153  {
154  return index_ < key_count_;
155  }
SlotIndex key_count_
same as stable_.get_key_count()

Here is the caller graph for this function:

void foedus::storage::masstree::MasstreeCursor::Route::setup_order ( )
inline

Definition at line 564 of file masstree_cursor.cpp.

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

564  {
566  // sort entries in this page
567  // we have already called prefetch_general(), which prefetches 4 cachelines (256 bytes).
568  // as we are reading up to slices_[key_count - 1], we might want to prefetch more.
569  MasstreeBorderPage* page = reinterpret_cast<MasstreeBorderPage*>(page_);
570  for (SlotIndex i = 0; i < key_count_; ++i) {
571  order_[i] = i;
572  }
573 
574  if (page->is_consecutive_inserts()) {
575  DVLOG(2) << "lucky, an already sorted border page.";
576  return;
577  }
578 
579  page->prefetch_additional_if_needed(key_count_);
580  struct Sorter {
581  explicit Sorter(const MasstreeBorderPage* target) : target_(target) {}
582  bool operator() (SlotIndex left, SlotIndex right) {
583  KeySlice left_slice = target_->get_slice(left);
584  KeySlice right_slice = target_->get_slice(right);
585  if (left_slice < right_slice) {
586  return true;
587  } else if (left_slice == right_slice) {
588  return target_->get_remainder_length(left) < target_->get_remainder_length(right);
589  } else {
590  return false;
591  }
592  }
593  const MasstreeBorderPage* target_;
594  };
595 
596  // this sort order in page is correct even without evaluating the suffix.
597  // however, to compare with our searching key, we need to consider suffix
598  std::sort(order_, order_ + key_count_, Sorter(page));
599 }
uint16_t SlotIndex
Index of a record in a (border) page.
bool is_border() const __attribute__((always_inline))
uint64_t KeySlice
Each key slice is an 8-byte integer.
SlotIndex key_count_
same as stable_.get_key_count()
SlotIndex order_[kBorderPageMaxSlots]
only for border.
#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::MasstreeCursor::Route::was_stably_moved ( ) const
inline

In almost all places of the cursor code, we check is_moved() only on the stable version so that the cursor can consistently decide whether to follow foster-twins or not.

So, we shouldn't have any "is_moved" in the file other than this.

Definition at line 161 of file masstree_cursor.hpp.

References foedus::storage::PageVersionStatus::is_moved().

161 { return stable_.is_moved(); }
bool is_moved() const __attribute__((always_inline))
Definition: page.hpp:71
PageVersionStatus stable_
version as of calculating order_.

Here is the call graph for this function:

Member Data Documentation

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::index_

index in ordered keys.

in interior, same.

Definition at line 113 of file masstree_cursor.hpp.

Referenced by get_cur_original_index().

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::index_mini_

only for interior.

Definition at line 115 of file masstree_cursor.hpp.

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::key_count_

same as stable_.get_key_count()

Note
Even in a border page, key_count_ might be zero. Such a case might happen right after no-record-split, split for a super-long key/value etc. We tolerate such a page in routes_, and just skip over it in next() etc.

Definition at line 122 of file masstree_cursor.hpp.

Referenced by is_valid_record(), and setup_order().

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::key_count_mini_

only for interior.

Definition at line 124 of file masstree_cursor.hpp.

KeySlice foedus::storage::masstree::MasstreeCursor::Route::latest_separator_

Upto which separator we are done.

only for interior. If forward search, we followed a pointer before this separator. If backward search, we followed a pointer after this separator. This is updated whenever we follow a pointer from this interior page, and used when we have to re-find the separator. In Master-tree, a separator never disappears from the page, so we can surely find this.

Definition at line 142 of file masstree_cursor.hpp.

Layer foedus::storage::masstree::MasstreeCursor::Route::layer_
MovedPageSearchStatus foedus::storage::masstree::MasstreeCursor::Route::moved_page_search_status_

only when stable_ indicates that this page is a moved page

Definition at line 132 of file masstree_cursor.hpp.

SlotIndex foedus::storage::masstree::MasstreeCursor::Route::order_[kBorderPageMaxSlots]

only for border.

order_[0] is the index of smallest record, [1] second smallest...

Definition at line 145 of file masstree_cursor.hpp.

Referenced by setup_order().

bool foedus::storage::masstree::MasstreeCursor::Route::snapshot_

whether page_ is a snapshot page

Definition at line 127 of file masstree_cursor.hpp.

PageVersionStatus foedus::storage::masstree::MasstreeCursor::Route::stable_

version as of calculating order_.

We also guarantee that we retrieved key_count_ and key_count_mini_ as-of OR after this version.

Q: Why it could be "after"? A: When we find that an intermediate page now has more separators, we need to re-search (rebase) in the page. In that case, the only thing we care is key_count_ and key_count_mini_. Version number of intermediate pages has no effect .. except is_moved(). But, even in that case, intermediate page has an invariant that we can just search in the old page. Thus, in either case, we don't update stable_ but only re-retrieve key_count_ and key_count_mini_.

Invariant
Once constructed this Route object, stable_ is immutable. We won't update it.

Definition at line 111 of file masstree_cursor.hpp.


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