libfoedus-core
FOEDUS Core Library
foedus::storage::masstree::GrowNonFirstLayerRoot Struct Referencefinal

A system transaction to grow a second- or depper-layer root. More...

Detailed Description

A system transaction to grow a second- or depper-layer root.

See also
Physical-only, short-living system transactions.

This does nothing and returns kErrorCodeOk in the following cases:

  • The root turns out to be not moved (already grown).
  • The parent turns out to be moved (split).

Grow is a non-mandatory operation. We can delay it.

Locks taken in this sysxct:

  • Record lock on the pointer in parent page.
  • Page-lock of the current root (will be retired).

Definition at line 79 of file masstree_grow_impl.hpp.

#include <masstree_grow_impl.hpp>

Inheritance diagram for foedus::storage::masstree::GrowNonFirstLayerRoot:
Collaboration diagram for foedus::storage::masstree::GrowNonFirstLayerRoot:

Public Member Functions

 GrowNonFirstLayerRoot (thread::Thread *context, MasstreeBorderPage *parent, uint16_t pointer_index)
 
virtual ErrorCode run (xct::SysxctWorkspace *sysxct_workspace) override
 Execute the system transaction. More...
 

Public Attributes

thread::Thread *const context_
 Thread context. More...
 
MasstreeBorderPage *const parent_
 The border page of the parent layer. More...
 
const uint16_t pointer_index_
 Index of the pointer in parent. More...
 

Constructor & Destructor Documentation

foedus::storage::masstree::GrowNonFirstLayerRoot::GrowNonFirstLayerRoot ( thread::Thread context,
MasstreeBorderPage parent,
uint16_t  pointer_index 
)
inline

Definition at line 91 of file masstree_grow_impl.hpp.

95  : xct::SysxctFunctor(),
96  context_(context),
97  parent_(parent),
98  pointer_index_(pointer_index) {
99  }
thread::Thread *const context_
Thread context.
MasstreeBorderPage *const parent_
The border page of the parent layer.
const uint16_t pointer_index_
Index of the pointer in parent.

Member Function Documentation

ErrorCode foedus::storage::masstree::GrowNonFirstLayerRoot::run ( xct::SysxctWorkspace sysxct_workspace)
overridevirtual

Execute the system transaction.

You should override this method.

Implements foedus::xct::SysxctFunctor.

Definition at line 167 of file masstree_grow_impl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, context_, foedus::storage::masstree::MasstreeBorderPage::does_point_to_layer(), foedus::storage::masstree::MasstreePage::get_foster_fence(), 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::MasstreeBorderPage::get_next_layer(), foedus::storage::masstree::MasstreeBorderPage::get_owner_id(), foedus::storage::masstree::MasstreePage::get_volatile_page_id(), foedus::storage::masstree::grow_case_a_common(), foedus::storage::masstree::grow_case_b_common(), foedus::storage::masstree::MasstreePage::header(), foedus::storage::masstree::MasstreePage::is_border(), foedus::xct::RwLockableXctId::is_keylocked(), foedus::storage::masstree::MasstreePage::is_layer_root(), foedus::storage::masstree::MasstreePage::is_locked(), foedus::storage::masstree::MasstreePage::is_moved(), foedus::storage::VolatilePagePointer::is_null(), foedus::storage::masstree::MasstreePage::is_retired(), foedus::kErrorCodeOk, parent_, pointer_index_, foedus::storage::PageHeader::snapshot_, foedus::storage::PageHeader::storage_id_, foedus::thread::Thread::sysxct_page_lock(), foedus::thread::Thread::sysxct_record_lock(), and foedus::storage::DualPagePointer::volatile_pointer_.

167  {
170  // Once it becomes a next-layer pointer, it never goes back to a normal record, thus this is safe.
172 
173  auto* record = parent_->get_owner_id(pointer_index_);
174  auto parent_page_id = parent_->get_volatile_page_id();
175  CHECK_ERROR_CODE(context_->sysxct_record_lock(sysxct_workspace, parent_page_id, record));
177 
178  // After locking the record, check the state of the pointer
179  if (record->is_moved()) {
180  DVLOG(0) << "Interesting. concurrent thread has split or is splitting the parent page.";
181  return kErrorCodeOk; // no hurry. root-grow can be delayed
182  }
183  ASSERT_ND(!record->is_deleted());
184  ASSERT_ND(record->is_next_layer());
185 
186  const auto& resolver = context_->get_global_volatile_page_resolver();
187  DualPagePointer* pointer = parent_->get_next_layer(pointer_index_);
188  ASSERT_ND(!pointer->volatile_pointer_.is_null());
189  Page* cur_root_page = resolver.resolve_offset(pointer->volatile_pointer_);
190  MasstreePage* cur_root = reinterpret_cast<MasstreePage*>(cur_root_page);
191  ASSERT_ND(cur_root->is_layer_root());
192 
193  CHECK_ERROR_CODE(context_->sysxct_page_lock(sysxct_workspace, cur_root_page));
194  ASSERT_ND(cur_root->is_locked());
195  // After locking the page, check the state of the page
196  if (!cur_root->is_moved()) {
197  DVLOG(0) << "Interesting. concurrent thread has already grown it.";
198  return kErrorCodeOk;
199  }
200 
201  // But, is_retired is impossible because we locked the parent record before following
202  ASSERT_ND(!cur_root->is_retired());
203  if (cur_root->get_foster_fence() == cur_root->get_low_fence()
204  || cur_root->get_foster_fence() == cur_root->get_high_fence()) {
205  DVLOG(1) << "Easier. Empty-range foster child for non-first layer root."
206  "storage_id=" << parent_->header().storage_id_;
207  grow_case_a_common(context_, pointer, cur_root);
208  } else {
209  DVLOG(0) << "Growing non-first layer root. storage_id=" << parent_->header().storage_id_;
210  CHECK_ERROR_CODE(grow_case_b_common(context_, pointer, cur_root));
211  }
212 
213  return kErrorCodeOk;
214 }
const memory::GlobalVolatilePageResolver & get_global_volatile_page_resolver() const
Returns the page resolver to convert page ID to page pointer.
Definition: thread.cpp:125
thread::Thread *const context_
Thread context.
ErrorCode sysxct_record_lock(xct::SysxctWorkspace *sysxct_workspace, storage::VolatilePagePointer page_id, xct::RwLockableXctId *lock)
Takes a lock for a sysxct running under this thread.
bool is_border() const __attribute__((always_inline))
StorageId storage_id_
ID of the storage this page belongs to.
Definition: page.hpp:196
DualPagePointer * get_next_layer(SlotIndex index) __attribute__((always_inline))
void grow_case_a_common(thread::Thread *context, DualPagePointer *pointer, MasstreePage *cur_root)
0 means no-error.
Definition: error_code.hpp:87
MasstreeBorderPage *const parent_
The border page of the parent layer.
ErrorCode sysxct_page_lock(xct::SysxctWorkspace *sysxct_workspace, storage::Page *page)
Takes a page lock in the same page for a sysxct running under this thread.
ErrorCode grow_case_b_common(thread::Thread *context, DualPagePointer *pointer, MasstreePage *cur_root)
const uint16_t pointer_index_
Index of the pointer in parent.
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
VolatilePagePointer get_volatile_page_id() const
xct::RwLockableXctId * get_owner_id(SlotIndex index) __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
bool does_point_to_layer(SlotIndex index) const __attribute__((always_inline))
bool is_keylocked() const __attribute__((always_inline))
Definition: xct_id.hpp:1140

Here is the call graph for this function:

Member Data Documentation

thread::Thread* const foedus::storage::masstree::GrowNonFirstLayerRoot::context_

Thread context.

Definition at line 81 of file masstree_grow_impl.hpp.

Referenced by run().

MasstreeBorderPage* const foedus::storage::masstree::GrowNonFirstLayerRoot::parent_

The border page of the parent layer.

Definition at line 85 of file masstree_grow_impl.hpp.

Referenced by run().

const uint16_t foedus::storage::masstree::GrowNonFirstLayerRoot::pointer_index_

Index of the pointer in parent.

Definition at line 89 of file masstree_grow_impl.hpp.

Referenced by run().


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