20 #include <glog/logging.h>
40 pages[1] =
reinterpret_cast<Page*
>(
old_);
45 VLOG(0) <<
"Interesting. concurrent thread has already split this node?";
48 VLOG(0) <<
"Interesting. concurrent thread already adopted.";
55 const auto pointer_index = minipage.
find_pointer(searching_slice);
74 uint16_t minipage_index,
75 uint16_t pointer_index) {
76 VLOG(0) <<
"Adopting from a child page that contains an empty-range page. This happens when"
77 <<
" record compaction/expansion created a page without a record.";
86 ASSERT_ND(!grandchild_major->header().snapshot_);
94 empty_grandchild = grandchild_minor;
95 nonempty_grandchild = grandchild_major;
97 empty_grandchild = grandchild_major;
98 nonempty_grandchild = grandchild_minor;
103 minipage.pointers_[pointer_index].snapshot_pointer_ = 0;
104 minipage.pointers_[pointer_index].volatile_pointer_ = nonempty_grandchild->
get_volatile_page_id();
119 uint16_t minipage_index,
120 uint16_t pointer_index) {
131 if (minipage.key_count_ == pointer_index) {
134 ASSERT_ND(!minipage.pointers_[pointer_index].is_both_null());
135 ASSERT_ND(pointer_index == 0 || minipage.separators_[pointer_index - 1] < new_separator);
136 minipage.separators_[pointer_index] = new_separator;
137 minipage.pointers_[pointer_index + 1].snapshot_pointer_ = 0;
138 minipage.pointers_[pointer_index + 1].volatile_pointer_ = major_pointer;
142 minipage.pointers_[pointer_index].snapshot_pointer_ = 0;
143 minipage.pointers_[pointer_index].volatile_pointer_ = minor_pointer;
148 ++minipage.key_count_;
164 new_minipage.separators_[j] = 0;
166 new_minipage.pointers_[j].snapshot_pointer_ = 0;
167 new_minipage.pointers_[j].volatile_pointer_.word = 0;
172 new_minipage.pointers_[0].snapshot_pointer_ = 0;
173 new_minipage.pointers_[0].volatile_pointer_ = major_pointer;
176 DualPagePointer& old_pointer = minipage.pointers_[minipage.key_count_];
207 split.split_impl_no_error(&free_pages_scope);
SlotIndex get_key_count() const __attribute__((always_inline))
physical key count (those keys might be deleted) in this page.
Represents a pointer to another page (usually a child page).
ErrorCode adopt_case_b(uint16_t minipage_index, uint16_t pointer_index)
bool is_empty_range() const __attribute__((always_inline))
An empty-range page, either intermediate or border, never has any entries.
ErrorCode sysxct_batch_page_locks(xct::SysxctWorkspace *sysxct_workspace, uint32_t lock_count, storage::Page **pages)
Takes a bunch of page locks for a sysxct running under this thread.
bool is_locked() const __attribute__((always_inline))
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
bool is_moved() const __attribute__((always_inline))
uint32_t PagePoolOffset
Offset in PagePool that compactly represents the page address (unlike 8 bytes pointer).
void collect_retired_volatile_page(storage::VolatilePagePointer ptr)
Keeps the specified volatile page as retired as of the current epoch.
MasstreePage *const old_
The old page that was split, whose foster-twins are being adopted.
Represents a pointer to a volatile page with modification count for preventing ABA.
MiniPage & get_minipage(uint8_t index) __attribute__((always_inline))
uint64_t KeySlice
Each key slice is an 8-byte integer.
const uint16_t kMaxIntermediateMiniSeparators
Max number of separators stored in the second level of intermediate pages.
Common base of MasstreeIntermediatePage and MasstreeBorderPage.
VolatilePagePointer get_foster_minor() const __attribute__((always_inline))
bool is_retired() const __attribute__((always_inline))
MasstreeIntermediatePage *const parent_
The parent page that currently points to the old page.
VolatilePagePointer get_foster_major() const __attribute__((always_inline))
ErrorCode grab(uint32_t count)
If this thread doesn't have enough free pages, no page is obtained, returning kErrorCodeMemoryNoFreeP...
VolatilePagePointer volatile_pointer_
ErrorCode adopt_case_a(uint16_t minipage_index, uint16_t pointer_index)
const uint16_t kMaxIntermediateSeparators
Max number of separators stored in the first level of intermediate pages.
thread::Thread *const context_
Thread context.
SnapshotPagePointer snapshot_pointer_
void increment_key_count() __attribute__((always_inline))
Just a marker to denote that the memory region represents a data page.
void set_retired() __attribute__((always_inline))
KeySlice get_high_fence() const __attribute__((always_inline))
P * resolve_cast(storage::VolatilePagePointer ptr) const
resolve() plus reinterpret_cast
void set_separator(uint8_t minipage_index, KeySlice new_separator)
Place a new separator for a new minipage.
KeySlice get_low_fence() const __attribute__((always_inline))
KeySlice get_foster_fence() const __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
const PageVersion * get_version_address() const __attribute__((always_inline))
VolatilePagePointer get_volatile_page_id() const
PageVersionStatus status_
void verify_separators() const
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
void memory_fence_release()
Equivalent to std::atomic_thread_fence(std::memory_order_release).
Obtains multiple free volatile pages at once and releases them automatically when this object gets ou...
ErrorCode
Enum of error codes defined in error_code.xmacro.
uint8_t find_minipage(KeySlice slice) const __attribute__((always_inline))
Navigates a searching key-slice to one of the mini pages in this page.
Per-thread reused work memory for system transactions.
uint8_t find_pointer(KeySlice slice) const __attribute__((always_inline))
Navigates a searching key-slice to one of pointers in this mini-page.
virtual ErrorCode run(xct::SysxctWorkspace *sysxct_workspace) override
Execute the system transaction.