libfoedus-core
FOEDUS Core Library
foedus::storage::sequential::SequentialPage Class Referencefinal

Represents one data page in Sequential Storage. More...

Detailed Description

Represents one data page in Sequential Storage.

In Sequential Storage, every data page is a leaf page that forms a singly linked list. So simple.

Page Layout
See Page Layout

This is a private implementation-details of Sequential Storage, thus file name ends with _impl. Do not include this header from a client program unless you know what you are doing.

Attention
Do NOT instantiate this object or derive from this class. A page is always reinterpret-ed from a pooled memory region. No meaningful RTTI.

Definition at line 53 of file sequential_page_impl.hpp.

#include <sequential_page_impl.hpp>

Public Member Functions

 SequentialPage ()=delete
 
 SequentialPage (const SequentialPage &other)=delete
 
SequentialPageoperator= (const SequentialPage &other)=delete
 
PageHeaderheader ()
 
const PageHeaderheader () const
 
uint16_t get_record_count () const
 Returns how many records in this page placed so far. More...
 
uint16_t get_used_data_bytes () const
 How many data bytes in this page consumed so far. More...
 
void assert_consistent () const
 
uint16_t get_payload_length (uint16_t record) const
 Returns byte length of payload of the specified record in this page. More...
 
void set_payload_length (uint16_t record, uint16_t length)
 Sets byte length of payload of the specified record in this page. More...
 
uint16_t get_record_length (uint16_t record) const
 Returns byte length of the specified record in this page. More...
 
void get_all_records_nosync (uint16_t *record_count, const char **record_pointers, uint16_t *payload_lengthes) const
 Retrieve positions and lengthes of all records in one batch. More...
 
uint16_t get_record_offset (uint16_t record) const
 Returns beginning offset of the specified record. More...
 
DualPagePointernext_page ()
 
const DualPagePointernext_page () const
 
void initialize_volatile_page (StorageId storage_id, VolatilePagePointer page_id)
 Called only when this page is initialized. More...
 
void initialize_snapshot_page (StorageId storage_id, SnapshotPagePointer page_id)
 
void append_record_nosync (xct::XctId owner_id, uint16_t payload_length, const void *payload)
 Appends a record to this page. More...
 
bool can_insert_record (uint16_t payload_length) const
 Returns if this page has enough room to insert a record with the given payload length. More...
 
Epoch get_first_record_epoch () const
 Returns the epoch of the fist record in this page (undefined behavior if no record). More...
 
xct::RwLockableXctIdowner_id_from_offset (uint16_t offset)
 
const xct::RwLockableXctIdowner_id_from_offset (uint16_t offset) const
 
uint32_t unused_dummy_func_filler () const
 

Constructor & Destructor Documentation

foedus::storage::sequential::SequentialPage::SequentialPage ( )
delete
foedus::storage::sequential::SequentialPage::SequentialPage ( const SequentialPage other)
delete

Member Function Documentation

void foedus::storage::sequential::SequentialPage::append_record_nosync ( xct::XctId  owner_id,
uint16_t  payload_length,
const void *  payload 
)
inline

Appends a record to this page.

This method assumes that there is no concurrent thread modifying this page (that's how we write both volatile and snapshot pages) and that the page has enough space.

Definition at line 155 of file sequential_page_impl.hpp.

References foedus::assorted::align8(), assert_consistent(), ASSERT_ND, get_record_count(), foedus::storage::PageVersionStatus::increment_version_counter(), foedus::storage::sequential::kDataSize, foedus::storage::PageHeader::key_count_, foedus::storage::sequential::kMaxSlots, foedus::storage::kRecordOverhead, foedus::xct::RwLockableXctId::lock_, foedus::assorted::memory_fence_release(), owner_id_from_offset(), foedus::storage::PageHeader::page_version_, foedus::xct::McsRwLock::reset(), set_payload_length(), foedus::storage::PageHeader::snapshot_, foedus::storage::PageVersion::status_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by foedus::storage::sequential::SequentialStoragePimpl::append_record(), and foedus::storage::sequential::SequentialComposer::compose().

158  {
159  uint16_t record = get_record_count();
160  ASSERT_ND(record < kMaxSlots);
161  ASSERT_ND(used_data_bytes_ + assorted::align8(payload_length) + kRecordOverhead <= kDataSize);
162  set_payload_length(record, payload_length);
163  xct::RwLockableXctId* owner_id_addr = owner_id_from_offset(used_data_bytes_);
164  owner_id_addr->xct_id_ = owner_id;
165  owner_id_addr->lock_.reset(); // not used...
166  std::memcpy(data_ + used_data_bytes_ + kRecordOverhead, payload, payload_length);
167  ++record_count_;
168  used_data_bytes_ += assorted::align8(payload_length) + kRecordOverhead;
169  header_.key_count_ = record_count_;
170  if (!header_.snapshot_) {
171  // to protect concurrent cursor, version counter must be written at last
173  }
174  // no need for lock to increment, just a barrier suffices. directly call status_.increment.
177  }
T align8(T value)
8-alignment.
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
xct::RwLockableXctId * owner_id_from_offset(uint16_t offset)
uint16_t key_count_
physical key count (those keys might be deleted) in this page.
Definition: page.hpp:219
PageVersion page_version_
Used in several storage types as concurrency control mechanism for the page.
Definition: page.hpp:272
PageVersionStatus status_
Definition: page.hpp:172
void set_payload_length(uint16_t record, uint16_t length)
Sets byte length of payload of the specified record in this page.
uint16_t get_record_count() const
Returns how many records in this page placed so far.
const uint16_t kDataSize
Byte size of data region in each data page of sequential storage.
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
void memory_fence_release()
Equivalent to std::atomic_thread_fence(std::memory_order_release).
const uint16_t kMaxSlots
We have to represent the record count in 15 bits.
void increment_version_counter() __attribute__((always_inline))
Definition: page.hpp:103

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::sequential::SequentialPage::assert_consistent ( ) const
inline

Definition at line 81 of file sequential_page_impl.hpp.

References ASSERT_ND, get_record_count(), get_used_data_bytes(), and foedus::storage::sequential::kDataSize.

Referenced by append_record_nosync(), get_all_records_nosync(), get_payload_length(), get_record_offset(), and set_payload_length().

81  {
82  ASSERT_ND(get_used_data_bytes() + get_record_count() * sizeof(PayloadLength) <= kDataSize);
83  }
uint16_t get_record_count() const
Returns how many records in this page placed so far.
const uint16_t kDataSize
Byte size of data region in each data page of sequential storage.
#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
uint16_t get_used_data_bytes() const
How many data bytes in this page consumed so far.

Here is the call graph for this function:

Here is the caller graph for this function:

bool foedus::storage::sequential::SequentialPage::can_insert_record ( uint16_t  payload_length) const
inline

Returns if this page has enough room to insert a record with the given payload length.

This method does not guarantee if you can really insert it due to concurrent appends. Thus, this method should be followed by append_record, which does real check and insert.

Definition at line 184 of file sequential_page_impl.hpp.

References foedus::assorted::align8(), foedus::storage::sequential::kDataSize, foedus::storage::sequential::kMaxSlots, and foedus::storage::kRecordOverhead.

Referenced by foedus::storage::sequential::SequentialStoragePimpl::append_record(), and foedus::storage::sequential::SequentialComposer::compose().

184  {
185  uint16_t record_length = assorted::align8(payload_length) + kRecordOverhead;
186  return used_data_bytes_ + record_length
187  + sizeof(PayloadLength) * (record_count_ + 1) <= kDataSize && record_count_ < kMaxSlots;
188  }
T align8(T value)
8-alignment.
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
const uint16_t kDataSize
Byte size of data region in each data page of sequential storage.
const uint16_t kMaxSlots
We have to represent the record count in 15 bits.

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::sequential::SequentialPage::get_all_records_nosync ( uint16_t *  record_count,
const char **  record_pointers,
uint16_t *  payload_lengthes 
) const
inline

Retrieve positions and lengthes of all records in one batch.

Definition at line 105 of file sequential_page_impl.hpp.

References foedus::assorted::align8(), assert_consistent(), get_payload_length(), get_record_count(), and foedus::storage::kRecordOverhead.

108  {
110  *record_count = get_record_count();
111  uint16_t position = 0;
112  for (uint16_t i = 0; i < *record_count; ++i) {
113  record_pointers[i] = data_ + position;
114  payload_lengthes[i] = get_payload_length(i);
115  position += assorted::align8(payload_lengthes[i]) + foedus::storage::kRecordOverhead;
116  }
117  }
T align8(T value)
8-alignment.
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
uint16_t get_payload_length(uint16_t record) const
Returns byte length of payload of the specified record in this page.
uint16_t get_record_count() const
Returns how many records in this page placed so far.

Here is the call graph for this function:

Epoch foedus::storage::sequential::SequentialPage::get_first_record_epoch ( ) const
inline

Returns the epoch of the fist record in this page (undefined behavior if no record).

Precondition
get_record_count()

Definition at line 193 of file sequential_page_impl.hpp.

References ASSERT_ND, foedus::xct::XctId::get_epoch(), get_record_count(), owner_id_from_offset(), and foedus::xct::RwLockableXctId::xct_id_.

Referenced by foedus::storage::sequential::SequentialStoragePimpl::append_record(), and foedus::storage::sequential::SequentialComposer::drop_volatiles().

193  {
195  const xct::RwLockableXctId* first_owner_id = owner_id_from_offset(0);
196  return first_owner_id->xct_id_.get_epoch();
197  }
xct::RwLockableXctId * owner_id_from_offset(uint16_t offset)
uint16_t get_record_count() const
Returns how many records in this page placed so far.
#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:

uint16_t foedus::storage::sequential::SequentialPage::get_payload_length ( uint16_t  record) const
inline

Returns byte length of payload of the specified record in this page.

Definition at line 86 of file sequential_page_impl.hpp.

References assert_consistent(), ASSERT_ND, get_record_count(), and foedus::storage::sequential::kDataSize.

Referenced by get_all_records_nosync(), get_record_length(), and get_record_offset().

86  {
87  ASSERT_ND(record < get_record_count());
89  const PayloadLength* lengthes = reinterpret_cast<const PayloadLength*>(data_ + kDataSize);
90  PayloadLength length = *(lengthes - 1 - record);
91  return length;
92  }
uint16_t get_record_count() const
Returns how many records in this page placed so far.
const uint16_t kDataSize
Byte size of data region in each data page of sequential storage.
#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:

uint16_t foedus::storage::sequential::SequentialPage::get_record_count ( ) const
inline

Returns how many records in this page placed so far.

Monotonically increasing. When the page becomes full, we go on to next page.

Invariant
0 <= record count <= kMaxSlots
Note
this method might return a stale information on volatile page. Use barrier or atomic CAS when needed.

Definition at line 71 of file sequential_page_impl.hpp.

Referenced by foedus::storage::sequential::SequentialStoragePimpl::append_record(), append_record_nosync(), assert_consistent(), foedus::storage::sequential::SequentialComposer::drop_volatiles(), get_all_records_nosync(), get_first_record_epoch(), get_payload_length(), get_record_offset(), and foedus::storage::sequential::operator<<().

71 { return record_count_; }

Here is the caller graph for this function:

uint16_t foedus::storage::sequential::SequentialPage::get_record_length ( uint16_t  record) const
inline

Returns byte length of the specified record in this page.

Definition at line 100 of file sequential_page_impl.hpp.

References get_payload_length(), and foedus::storage::kRecordOverhead.

100  {
102  }
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
uint16_t get_payload_length(uint16_t record) const
Returns byte length of payload of the specified record in this page.

Here is the call graph for this function:

uint16_t foedus::storage::sequential::SequentialPage::get_record_offset ( uint16_t  record) const
inline

Returns beginning offset of the specified record.

Definition at line 119 of file sequential_page_impl.hpp.

References foedus::assorted::align8(), assert_consistent(), ASSERT_ND, get_payload_length(), get_record_count(), and foedus::storage::kRecordOverhead.

119  {
121  ASSERT_ND(record < get_record_count());
122  uint16_t offset = 0;
123  for (uint16_t i = 0; i < record; ++i) {
124  uint16_t payload_length = get_payload_length(i);
125  offset += assorted::align8(payload_length) + foedus::storage::kRecordOverhead;
126  }
127  return offset;
128  }
T align8(T value)
8-alignment.
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
uint16_t get_payload_length(uint16_t record) const
Returns byte length of payload of the specified record in this page.
uint16_t get_record_count() const
Returns how many records in this page placed so far.
#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:

uint16_t foedus::storage::sequential::SequentialPage::get_used_data_bytes ( ) const
inline

How many data bytes in this page consumed so far.

Monotonically increasing. When the page becomes full, we go on to next page.

Invariant
0 <= used data bytes <= kDataSize
Note
this method might return a stale information on volatile page. Use barrier or atomic CAS when needed.

Definition at line 79 of file sequential_page_impl.hpp.

Referenced by assert_consistent().

79 { return used_data_bytes_; }

Here is the caller graph for this function:

PageHeader& foedus::storage::sequential::SequentialPage::header ( )
inline

Definition at line 61 of file sequential_page_impl.hpp.

Referenced by foedus::storage::sequential::SequentialComposer::compose().

61 { return header_; }

Here is the caller graph for this function:

const PageHeader& foedus::storage::sequential::SequentialPage::header ( ) const
inline

Definition at line 62 of file sequential_page_impl.hpp.

62 { return header_; }
void foedus::storage::sequential::SequentialPage::initialize_snapshot_page ( StorageId  storage_id,
SnapshotPagePointer  page_id 
)
inline

Definition at line 141 of file sequential_page_impl.hpp.

References foedus::storage::PageHeader::init_snapshot(), foedus::storage::kSequentialPageType, foedus::storage::DualPagePointer::snapshot_pointer_, foedus::storage::DualPagePointer::volatile_pointer_, and foedus::storage::VolatilePagePointer::word.

Referenced by foedus::storage::sequential::SequentialComposer::compose().

141  {
142  header_.init_snapshot(page_id, storage_id, kSequentialPageType);
143  record_count_ = 0;
144  used_data_bytes_ = 0;
145  next_page_.snapshot_pointer_ = 0;
146  next_page_.volatile_pointer_.word = 0;
147  }
VolatilePagePointer volatile_pointer_
Definition: storage_id.hpp:308
SnapshotPagePointer snapshot_pointer_
Definition: storage_id.hpp:307
void init_snapshot(SnapshotPagePointer page_id, StorageId storage_id, PageType page_type) __attribute__((always_inline))
Definition: page.hpp:301

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::sequential::SequentialPage::initialize_volatile_page ( StorageId  storage_id,
VolatilePagePointer  page_id 
)
inline

Called only when this page is initialized.

Definition at line 134 of file sequential_page_impl.hpp.

References foedus::storage::PageHeader::init_volatile(), foedus::storage::kSequentialPageType, foedus::storage::DualPagePointer::snapshot_pointer_, foedus::storage::DualPagePointer::volatile_pointer_, and foedus::storage::VolatilePagePointer::word.

Referenced by foedus::storage::sequential::SequentialStoragePimpl::append_record().

134  {
135  header_.init_volatile(page_id, storage_id, kSequentialPageType);
136  record_count_ = 0;
137  used_data_bytes_ = 0;
138  next_page_.snapshot_pointer_ = 0;
139  next_page_.volatile_pointer_.word = 0;
140  }
void init_volatile(VolatilePagePointer page_id, StorageId storage_id, PageType page_type) __attribute__((always_inline))
Definition: page.hpp:284
VolatilePagePointer volatile_pointer_
Definition: storage_id.hpp:308
SnapshotPagePointer snapshot_pointer_
Definition: storage_id.hpp:307

Here is the call graph for this function:

Here is the caller graph for this function:

DualPagePointer& foedus::storage::sequential::SequentialPage::next_page ( )
inline
const DualPagePointer& foedus::storage::sequential::SequentialPage::next_page ( ) const
inline

Definition at line 131 of file sequential_page_impl.hpp.

131 { return next_page_; }
SequentialPage& foedus::storage::sequential::SequentialPage::operator= ( const SequentialPage other)
delete
xct::RwLockableXctId* foedus::storage::sequential::SequentialPage::owner_id_from_offset ( uint16_t  offset)
inline

Definition at line 199 of file sequential_page_impl.hpp.

Referenced by append_record_nosync(), and get_first_record_epoch().

199  {
200  return reinterpret_cast<xct::RwLockableXctId*>(data_ + offset);
201  }

Here is the caller graph for this function:

const xct::RwLockableXctId* foedus::storage::sequential::SequentialPage::owner_id_from_offset ( uint16_t  offset) const
inline

Definition at line 202 of file sequential_page_impl.hpp.

202  {
203  return reinterpret_cast<const xct::RwLockableXctId*>(data_ + offset);
204  }
void foedus::storage::sequential::SequentialPage::set_payload_length ( uint16_t  record,
uint16_t  length 
)
inline

Sets byte length of payload of the specified record in this page.

Definition at line 94 of file sequential_page_impl.hpp.

References assert_consistent(), and foedus::storage::sequential::kDataSize.

Referenced by append_record_nosync().

94  {
96  PayloadLength* lengthes = reinterpret_cast<PayloadLength*>(data_ + kDataSize);
97  *(lengthes - 1 - record) = length;
98  }
const uint16_t kDataSize
Byte size of data region in each data page of sequential storage.

Here is the call graph for this function:

Here is the caller graph for this function:

uint32_t foedus::storage::sequential::SequentialPage::unused_dummy_func_filler ( ) const
inline

Definition at line 206 of file sequential_page_impl.hpp.

206 { return filler_; }

The documentation for this class was generated from the following file: