libfoedus-core
FOEDUS Core Library
foedus::storage::array::ArrayStoragePimpl Class Referencefinal

Pimpl object of ArrayStorage. More...

Detailed Description

Pimpl object of ArrayStorage.

A private pimpl object for ArrayStorage. Do not include this header from a client program unless you know what you are doing.

Definition at line 88 of file array_storage_pimpl.hpp.

#include <array_storage_pimpl.hpp>

Collaboration diagram for foedus::storage::array::ArrayStoragePimpl:

Public Types

enum  Constants { kBatchMax = 16 }
 

Public Member Functions

 ArrayStoragePimpl ()=delete
 
 ArrayStoragePimpl (ArrayStorage *storage)
 
 ArrayStoragePimpl (Engine *engine, ArrayStorageControlBlock *control_block)
 
 ~ArrayStoragePimpl ()
 
ErrorStack create (const Metadata &metadata)
 
ErrorStack load (const StorageControlBlock &snapshot_block)
 
ErrorStack load_empty ()
 
void report_page_distribution ()
 
bool exists () const
 
const ArrayMetadataget_meta () const
 
StorageId get_id () const
 
uint16_t get_levels () const
 
uint16_t get_snapshot_drop_volatile_pages_threshold () const
 
uint16_t get_payload_size () const
 
ArrayOffset get_array_size () const
 
ErrorCode get_root_page (thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
 
ErrorStack verify_single_thread (thread::Thread *context)
 
ErrorStack verify_single_thread (thread::Thread *context, ArrayPage *page)
 
ErrorStack hcc_reset_all_temperature_stat ()
 
ErrorStack hcc_reset_all_temperature_stat_intermediate (VolatilePagePointer intermediate_page_id)
 
ErrorCode prefetch_pages (thread::Thread *context, bool install_volatile, bool cache_snapshot, ArrayOffset from, ArrayOffset to)
 defined in array_storage_prefetch.cpp More...
 
ErrorCode prefetch_pages_recurse (thread::Thread *context, bool install_volatile, bool cache_snapshot, ArrayOffset from, ArrayOffset to, ArrayPage *page)
 
ErrorCode locate_record_for_read (thread::Thread *context, ArrayOffset offset, Record **out, bool *snapshot_record) __attribute__((always_inline))
 
ErrorCode locate_record_for_write (thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
 
ErrorCode get_record (thread::Thread *context, ArrayOffset offset, void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
 
template<typename T >
ErrorCode get_record_primitive (thread::Thread *context, ArrayOffset offset, T *payload, uint16_t payload_offset)
 
ErrorCode get_record_payload (thread::Thread *context, ArrayOffset offset, const void **payload) __attribute__((always_inline))
 
ErrorCode get_record_for_write (thread::Thread *context, ArrayOffset offset, Record **record) __attribute__((always_inline))
 
template<typename T >
ErrorCode get_record_primitive_batch (thread::Thread *context, uint16_t payload_offset, uint16_t batch_size, const ArrayOffset *offset_batch, T *payload_batch) __attribute__((always_inline))
 
ErrorCode get_record_payload_batch (thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, const void **payload_batch) __attribute__((always_inline))
 
ErrorCode get_record_for_write_batch (thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch) __attribute__((always_inline))
 
ErrorCode overwrite_record (thread::Thread *context, ArrayOffset offset, const void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
 
template<typename T >
ErrorCode overwrite_record_primitive (thread::Thread *context, ArrayOffset offset, T payload, uint16_t payload_offset)
 
ErrorCode overwrite_record (thread::Thread *context, ArrayOffset offset, Record *record, const void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
 
template<typename T >
ErrorCode overwrite_record_primitive (thread::Thread *context, ArrayOffset offset, Record *record, T payload, uint16_t payload_offset) __attribute__((always_inline))
 
template<typename T >
ErrorCode increment_record (thread::Thread *context, ArrayOffset offset, T *value, uint16_t payload_offset)
 
template<typename T >
ErrorCode increment_record_oneshot (thread::Thread *context, ArrayOffset offset, T value, uint16_t payload_offset)
 
ErrorCode lookup_for_read (thread::Thread *context, ArrayOffset offset, ArrayPage **out, uint16_t *index, bool *snapshot_page) __attribute__((always_inline))
 
ErrorCode lookup_for_write (thread::Thread *context, ArrayOffset offset, ArrayPage **out, uint16_t *index) __attribute__((always_inline))
 This version always returns a volatile page, installing a new one if needed. More...
 
ErrorCode locate_record_for_read_batch (thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **out_batch, bool *snapshot_page_batch)
 
ErrorCode lookup_for_read_batch (thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, ArrayPage **out_batch, uint16_t *index_batch, bool *snapshot_page_batch)
 
ErrorCode lookup_for_write_batch (thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch)
 
ErrorCode follow_pointer (thread::Thread *context, bool in_snapshot, bool for_write, DualPagePointer *pointer, ArrayPage **out, const ArrayPage *parent, uint16_t index_in_parent) __attribute__((always_inline))
 
ErrorCode follow_pointers_for_read_batch (thread::Thread *context, uint16_t batch_size, bool *in_snapshot, ArrayPage **parents, const uint16_t *index_in_parents, ArrayPage **out)
 
ErrorCode follow_pointers_for_write_batch (thread::Thread *context, uint16_t batch_size, ArrayPage **parents, const uint16_t *index_in_parents, ArrayPage **out)
 

Static Public Member Functions

static void release_pages_recursive (const memory::GlobalVolatilePageResolver &resolver, memory::PageReleaseBatch *batch, VolatilePagePointer volatile_page_id)
 Used only from drop() More...
 
static std::vector< uint64_t > calculate_required_pages (uint64_t array_size, uint16_t payload)
 Calculate leaf/interior pages we need. More...
 
static std::vector< uint64_t > calculate_offset_intervals (uint8_t levels, uint16_t payload)
 The offset interval a single page represents in each level. More...
 

Public Attributes

Engine *const engine_
 
ArrayStorageControlBlock *const control_block_
 

Member Enumeration Documentation

Enumerator
kBatchMax 

If you want more than this, you should loop.

ArrayStorage should take care of it.

Definition at line 90 of file array_storage_pimpl.hpp.

90  {
92  kBatchMax = 16,
93  };
If you want more than this, you should loop.

Constructor & Destructor Documentation

foedus::storage::array::ArrayStoragePimpl::ArrayStoragePimpl ( )
delete
foedus::storage::array::ArrayStoragePimpl::ArrayStoragePimpl ( ArrayStorage storage)
inlineexplicit

Definition at line 96 of file array_storage_pimpl.hpp.

97  : engine_(storage->get_engine()), control_block_(storage->get_control_block()) {}
ArrayStorageControlBlock *const control_block_
foedus::storage::array::ArrayStoragePimpl::ArrayStoragePimpl ( Engine engine,
ArrayStorageControlBlock control_block 
)
inline

Definition at line 98 of file array_storage_pimpl.hpp.

99  : engine_(engine), control_block_(control_block) {}
ArrayStorageControlBlock *const control_block_
foedus::storage::array::ArrayStoragePimpl::~ArrayStoragePimpl ( )
inline

Definition at line 101 of file array_storage_pimpl.hpp.

101 {}

Member Function Documentation

std::vector< uint64_t > foedus::storage::array::ArrayStoragePimpl::calculate_offset_intervals ( uint8_t  levels,
uint16_t  payload 
)
static

The offset interval a single page represents in each level.

index=level. So, offset_intervals[0] is the number of records in a leaf page.

Definition at line 241 of file array_storage_pimpl.cpp.

References foedus::assorted::align8(), foedus::storage::array::kDataSize, foedus::storage::array::kInteriorFanout, and foedus::storage::kRecordOverhead.

243  {
244  const uint16_t payload_size_aligned = (assorted::align8(payload));
245 
246  std::vector<uint64_t> offset_intervals;
247  offset_intervals.push_back(kDataSize / (payload_size_aligned + kRecordOverhead));
248  for (uint8_t level = 1; level < levels; ++level) {
249  offset_intervals.push_back(offset_intervals[level - 1] * kInteriorFanout);
250  }
251  return offset_intervals;
252 }
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 page of array storage.
Definition: array_id.hpp:100
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110

Here is the call graph for this function:

std::vector< uint64_t > foedus::storage::array::ArrayStoragePimpl::calculate_required_pages ( uint64_t  array_size,
uint16_t  payload 
)
static

Calculate leaf/interior pages we need.

Returns
index=level.

Definition at line 170 of file array_storage_pimpl.cpp.

References foedus::assorted::align8(), foedus::assorted::int_div_ceil(), foedus::storage::array::kDataSize, foedus::storage::array::kInteriorFanout, and foedus::storage::kRecordOverhead.

171  {
172  payload = assorted::align8(payload);
173  uint64_t records_per_page = kDataSize / (payload + kRecordOverhead);
174 
175  // so, how many leaf pages do we need?
176  uint64_t leaf_pages = assorted::int_div_ceil(array_size, records_per_page);
177  LOG(INFO) << "We need " << leaf_pages << " leaf pages";
178 
179  // interior nodes
180  uint64_t total_pages = leaf_pages;
181  std::vector<uint64_t> pages;
182  pages.push_back(leaf_pages);
183  while (pages.back() != 1) {
184  uint64_t next_level_pages = assorted::int_div_ceil(pages.back(), kInteriorFanout);
185  LOG(INFO) << "Level-" << pages.size() << " would have " << next_level_pages << " pages";
186  pages.push_back(next_level_pages);
187  total_pages += next_level_pages;
188  }
189 
190  LOG(INFO) << "In total, we need " << total_pages << " pages";
191  return pages;
192 }
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 page of array storage.
Definition: array_id.hpp:100
int64_t int_div_ceil(int64_t dividee, int64_t dividor)
Efficient ceil(dividee/dividor) for integer.
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110

Here is the call graph for this function:

ErrorStack foedus::storage::array::ArrayStoragePimpl::create ( const Metadata metadata)

Definition at line 288 of file array_storage_pimpl.cpp.

References CHECK_ERROR, control_block_, ERROR_STACK, exists(), foedus::storage::Metadata::id_, foedus::kErrorCodeStrAlreadyExists, foedus::storage::kExists, foedus::kRetOk, load_empty(), foedus::storage::array::ArrayStorageControlBlock::meta_, and foedus::storage::array::ArrayStorageControlBlock::status_.

Referenced by foedus::storage::array::ArrayStorage::create().

288  {
289  if (exists()) {
290  LOG(ERROR) << "This array-storage already exists-" << metadata.id_;
292  }
293  control_block_->meta_ = static_cast<const ArrayMetadata&>(metadata);
295  LOG(INFO) << "Newly created an array-storage " << metadata.id_;
296 
298  return kRetOk;
299 }
StorageStatus status_
Status of the storage.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
The storage has been created and ready for use.
Definition: storage_id.hpp:158
ArrayMetadata meta_
metadata of this storage.
ArrayStorageControlBlock *const control_block_
0x0802 : "STORAGE: This storage already exists" .
Definition: error_code.hpp:168
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
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:

bool foedus::storage::array::ArrayStoragePimpl::exists ( ) const
inline

Definition at line 109 of file array_storage_pimpl.hpp.

References control_block_, and foedus::storage::array::ArrayStorageControlBlock::exists().

Referenced by create(), locate_record_for_read(), locate_record_for_write(), lookup_for_read(), and lookup_for_write().

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::follow_pointer ( thread::Thread context,
bool  in_snapshot,
bool  for_write,
DualPagePointer pointer,
ArrayPage **  out,
const ArrayPage parent,
uint16_t  index_in_parent 
)
inline

Definition at line 304 of file array_storage_pimpl.hpp.

References foedus::storage::array::array_volatile_page_init(), ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::follow_page_pointer(), foedus::storage::array::ArrayPage::get_level(), get_payload_size(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), and foedus::kErrorCodeOk.

Referenced by lookup_for_read(), and lookup_for_write().

311  {
312  ASSERT_ND(!in_snapshot || !for_write); // if we are modifying, we must be in volatile world
313  ASSERT_ND(!parent->is_leaf());
314  CHECK_ERROR_CODE(context->follow_page_pointer(
315  array_volatile_page_init, // array might have null pointer. in that case create empty new page
316  false, // if both volatile/snapshot null, create a new volatile (logically all-zero)
317  for_write,
318  !in_snapshot, // if we are already in snapshot world, no need to take more pointer set
319  pointer,
320  reinterpret_cast<Page**>(out),
321  reinterpret_cast<const Page*>(parent),
322  index_in_parent));
323 
324 #ifndef NDEBUG
325  ArrayPage* page = *out;
326  ASSERT_ND(page != nullptr);
327  ASSERT_ND(page->get_level() + 1U == parent->get_level());
328  if (page->is_leaf()) {
329  xct::XctId xct_id = page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_;
330  ASSERT_ND(xct_id.is_valid());
331  }
332 #endif // NDEBUG
333  return kErrorCodeOk;
334 }
void array_volatile_page_init(const VolatilePageInitArguments &args)
volatile page initialize callback for ArrayPage.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::follow_pointers_for_read_batch ( thread::Thread context,
uint16_t  batch_size,
bool *  in_snapshot,
ArrayPage **  parents,
const uint16_t *  index_in_parents,
ArrayPage **  out 
)

Definition at line 1010 of file array_storage_pimpl.cpp.

References foedus::storage::array::array_volatile_page_init(), ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::follow_page_pointers_for_read_batch(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), foedus::storage::array::ArrayPage::get_level(), get_payload_size(), foedus::storage::array::ArrayPage::header(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), kBatchMax, foedus::kErrorCodeOk, foedus::storage::Record::owner_id_, foedus::storage::PageHeader::snapshot_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by lookup_for_read_batch().

1016  {
1017  DualPagePointer* pointers[kBatchMax];
1018  for (uint8_t i = 0; i < batch_size; ++i) {
1019  ASSERT_ND(!parents[i]->is_leaf());
1020  ASSERT_ND(in_snapshot[i] == parents[i]->header().snapshot_);
1021  pointers[i] = &parents[i]->get_interior_record(index_in_parents[i]);
1022  }
1023 
1024 #ifndef NDEBUG
1025  // there is a case of out==parents. for the assertion below, let's copy
1026  ArrayPage* parents_copy[kBatchMax];
1027  for (uint8_t i = 0; i < batch_size; ++i) {
1028  parents_copy[i] = parents[i];
1029  }
1030 #endif // NDEBUG
1031 
1032  CHECK_ERROR_CODE(context->follow_page_pointers_for_read_batch(
1033  batch_size,
1035  false,
1036  true,
1037  pointers,
1038  reinterpret_cast<Page**>(parents),
1039  index_in_parents,
1040  in_snapshot,
1041  reinterpret_cast<Page**>(out)));
1042 
1043 #ifndef NDEBUG
1044  for (uint8_t i = 0; i < batch_size; ++i) {
1045  ArrayPage* page = out[i];
1046  ASSERT_ND(page != nullptr);
1047  /*
1048  if ((uintptr_t)(page) == 0xdadadadadadadadaULL) {
1049  for (uint8_t j = 0; j < batch_size; ++j) {
1050  in_snapshot[j] = parents_copy[j]->header().snapshot_;
1051  }
1052  CHECK_ERROR_CODE(context->follow_page_pointers_for_read_batch(
1053  batch_size,
1054  array_volatile_page_init,
1055  false,
1056  true,
1057  pointers,
1058  reinterpret_cast<Page**>(parents_copy),
1059  index_in_parents,
1060  in_snapshot,
1061  reinterpret_cast<Page**>(out)));
1062  }
1063  */
1064  ASSERT_ND(in_snapshot[i] == page->header().snapshot_);
1065  ASSERT_ND(page->get_level() + 1U == parents_copy[i]->get_level());
1066  if (page->is_leaf()) {
1067  xct::XctId xct_id = page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_;
1068  ASSERT_ND(xct_id.is_valid());
1069  }
1070  }
1071 #endif // NDEBUG
1072  return kErrorCodeOk;
1073 }
void array_volatile_page_init(const VolatilePageInitArguments &args)
volatile page initialize callback for ArrayPage.
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::follow_pointers_for_write_batch ( thread::Thread context,
uint16_t  batch_size,
ArrayPage **  parents,
const uint16_t *  index_in_parents,
ArrayPage **  out 
)

Definition at line 1075 of file array_storage_pimpl.cpp.

References foedus::storage::array::array_volatile_page_init(), ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::follow_page_pointers_for_write_batch(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), foedus::storage::array::ArrayPage::get_level(), get_payload_size(), foedus::storage::array::ArrayPage::header(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), kBatchMax, foedus::kErrorCodeOk, foedus::storage::Record::owner_id_, foedus::storage::PageHeader::snapshot_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by lookup_for_write_batch().

1080  {
1081  DualPagePointer* pointers[kBatchMax];
1082  for (uint8_t i = 0; i < batch_size; ++i) {
1083  ASSERT_ND(!parents[i]->is_leaf());
1084  ASSERT_ND(!parents[i]->header().snapshot_);
1085  pointers[i] = &parents[i]->get_interior_record(index_in_parents[i]);
1086  }
1087 
1088 #ifndef NDEBUG
1089  // there is a case of out==parents. for the assertion below, let's copy
1090  ArrayPage* parents_copy[kBatchMax];
1091  for (uint8_t i = 0; i < batch_size; ++i) {
1092  parents_copy[i] = parents[i];
1093  }
1094 #endif // NDEBUG
1095 
1096  CHECK_ERROR_CODE(context->follow_page_pointers_for_write_batch(
1097  batch_size,
1099  pointers,
1100  reinterpret_cast<Page**>(parents),
1101  index_in_parents,
1102  reinterpret_cast<Page**>(out)));
1103 
1104 #ifndef NDEBUG
1105  for (uint8_t i = 0; i < batch_size; ++i) {
1106  ArrayPage* page = out[i];
1107  ASSERT_ND(page != nullptr);
1108  ASSERT_ND(!page->header().snapshot_);
1109  ASSERT_ND(page->get_level() + 1U == parents_copy[i]->get_level());
1110  if (page->is_leaf()) {
1111  xct::XctId xct_id = page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_;
1112  ASSERT_ND(xct_id.is_valid());
1113  }
1114  }
1115 #endif // NDEBUG
1116  return kErrorCodeOk;
1117 }
void array_volatile_page_init(const VolatilePageInitArguments &args)
volatile page initialize callback for ArrayPage.
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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:

ArrayOffset foedus::storage::array::ArrayStoragePimpl::get_array_size ( ) const
inline

Definition at line 117 of file array_storage_pimpl.hpp.

References foedus::storage::array::ArrayMetadata::array_size_, and get_meta().

Referenced by locate_record_for_read(), locate_record_for_write(), lookup_for_read(), lookup_for_read_batch(), lookup_for_write(), and lookup_for_write_batch().

117 { return get_meta().array_size_; }
ArrayOffset array_size_
Size of this array.

Here is the call graph for this function:

Here is the caller graph for this function:

StorageId foedus::storage::array::ArrayStoragePimpl::get_id ( ) const
inline

Definition at line 111 of file array_storage_pimpl.hpp.

References get_meta(), and foedus::storage::Metadata::id_.

Referenced by increment_record(), increment_record_oneshot(), load_empty(), lookup_for_read_batch(), lookup_for_write_batch(), overwrite_record(), and overwrite_record_primitive().

111 { return get_meta().id_; }
StorageId id_
the unique ID of this storage.
Definition: metadata.hpp:103

Here is the call graph for this function:

Here is the caller graph for this function:

uint16_t foedus::storage::array::ArrayStoragePimpl::get_levels ( ) const
inline

Definition at line 112 of file array_storage_pimpl.hpp.

References control_block_, and foedus::storage::array::ArrayStorageControlBlock::levels_.

Referenced by lookup_for_read(), lookup_for_read_batch(), lookup_for_write(), and lookup_for_write_batch().

112 { return control_block_->levels_; }
ArrayStorageControlBlock *const control_block_

Here is the caller graph for this function:

const ArrayMetadata& foedus::storage::array::ArrayStoragePimpl::get_meta ( ) const
inline

Definition at line 110 of file array_storage_pimpl.hpp.

References control_block_, and foedus::storage::array::ArrayStorageControlBlock::meta_.

Referenced by get_array_size(), get_id(), get_payload_size(), get_snapshot_drop_volatile_pages_threshold(), load(), and prefetch_pages().

110 { return control_block_->meta_; }
ArrayMetadata meta_
metadata of this storage.
ArrayStorageControlBlock *const control_block_

Here is the caller graph for this function:

uint16_t foedus::storage::array::ArrayStoragePimpl::get_payload_size ( ) const
inline
ErrorCode foedus::storage::array::ArrayStoragePimpl::get_record ( thread::Thread context,
ArrayOffset  offset,
void *  payload,
uint16_t  payload_offset,
uint16_t  payload_count 
)
inline

Definition at line 372 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), get_payload_size(), foedus::kErrorCodeOk, locate_record_for_read(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, and foedus::storage::Record::payload_.

Referenced by foedus::storage::array::ArrayStorage::get_record().

377  {
378  ASSERT_ND(payload_offset + payload_count <= get_payload_size());
379  Record *record = nullptr;
380  bool snapshot_record;
381  CHECK_ERROR_CODE(locate_record_for_read(context, offset, &record, &snapshot_record));
382  CHECK_ERROR_CODE(context->get_current_xct().on_record_read(false, &record->owner_id_));
383  std::memcpy(payload, record->payload_ + payload_offset, payload_count);
384  return kErrorCodeOk;
385 }
ErrorCode locate_record_for_read(thread::Thread *context, ArrayOffset offset, Record **out, bool *snapshot_record) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::get_record_for_write ( thread::Thread context,
ArrayOffset  offset,
Record **  record 
)
inline

Definition at line 419 of file array_storage_pimpl.cpp.

References CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), foedus::xct::Xct::get_isolation_level(), foedus::xct::kDirtyRead, foedus::kErrorCodeOk, locate_record_for_write(), and foedus::xct::Xct::on_record_read().

Referenced by foedus::storage::array::ArrayStorage::get_record_for_write().

422  {
423  CHECK_ERROR_CODE(locate_record_for_write(context, offset, record));
424  xct::Xct& current_xct = context->get_current_xct();
425  if (current_xct.get_isolation_level() != xct::kDirtyRead) {
426  CHECK_ERROR_CODE(current_xct.on_record_read(true, &(*record)->owner_id_));
427  }
428  return kErrorCodeOk;
429 }
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
No guarantee at all for reads, for the sake of best performance and scalability.
Definition: xct_id.hpp:65

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::get_record_for_write_batch ( thread::Thread context,
uint16_t  batch_size,
const ArrayOffset offset_batch,
Record **  record_batch 
)
inline

Definition at line 746 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), foedus::xct::Xct::get_isolation_level(), kBatchMax, foedus::xct::kDirtyRead, foedus::kErrorCodeOk, lookup_for_write_batch(), foedus::assorted::memory_fence_consume(), foedus::xct::Xct::on_record_read(), and foedus::storage::Record::owner_id_.

Referenced by foedus::storage::array::ArrayStorage::get_record_for_write_batch().

750  {
751  ASSERT_ND(batch_size <= kBatchMax);
753  context,
754  batch_size,
755  offset_batch,
756  record_batch));
757  xct::Xct& current_xct = context->get_current_xct();
758  if (current_xct.get_isolation_level() != xct::kDirtyRead) {
759  for (uint8_t i = 0; i < batch_size; ++i) {
760  CHECK_ERROR_CODE(current_xct.on_record_read(true, &record_batch[i]->owner_id_));
761  }
763  }
764  return kErrorCodeOk;
765 }
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
ErrorCode lookup_for_write_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch)
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
void memory_fence_consume()
Equivalent to std::atomic_thread_fence(std::memory_order_consume).
No guarantee at all for reads, for the sake of best performance and scalability.
Definition: xct_id.hpp:65
#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::array::ArrayStoragePimpl::get_record_payload ( thread::Thread context,
ArrayOffset  offset,
const void **  payload 
)
inline

Definition at line 403 of file array_storage_pimpl.cpp.

References CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), foedus::xct::Xct::get_isolation_level(), foedus::xct::kDirtyRead, foedus::kErrorCodeOk, locate_record_for_read(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, and foedus::storage::Record::payload_.

Referenced by foedus::storage::array::ArrayStorage::get_record_payload().

406  {
407  Record *record = nullptr;
408  bool snapshot_record;
409  CHECK_ERROR_CODE(locate_record_for_read(context, offset, &record, &snapshot_record));
410  xct::Xct& current_xct = context->get_current_xct();
411  if (!snapshot_record &&
412  current_xct.get_isolation_level() != xct::kDirtyRead) {
413  CHECK_ERROR_CODE(current_xct.on_record_read(false, &record->owner_id_));
414  }
415  *payload = record->payload_;
416  return kErrorCodeOk;
417 }
ErrorCode locate_record_for_read(thread::Thread *context, ArrayOffset offset, Record **out, bool *snapshot_record) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
No guarantee at all for reads, for the sake of best performance and scalability.
Definition: xct_id.hpp:65

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::get_record_payload_batch ( thread::Thread context,
uint16_t  batch_size,
const ArrayOffset offset_batch,
const void **  payload_batch 
)
inline

Definition at line 717 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), foedus::xct::Xct::get_isolation_level(), kBatchMax, foedus::xct::kDirtyRead, foedus::kErrorCodeOk, locate_record_for_read_batch(), foedus::assorted::memory_fence_consume(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, and foedus::storage::Record::payload_.

Referenced by foedus::storage::array::ArrayStorage::get_record_payload_batch().

721  {
722  ASSERT_ND(batch_size <= kBatchMax);
723  Record* record_batch[kBatchMax];
724  bool snapshot_record_batch[kBatchMax];
726  context,
727  batch_size,
728  offset_batch,
729  record_batch,
730  snapshot_record_batch));
731  xct::Xct& current_xct = context->get_current_xct();
732  if (current_xct.get_isolation_level() != xct::kDirtyRead) {
733  for (uint8_t i = 0; i < batch_size; ++i) {
734  if (!snapshot_record_batch[i]) {
735  CHECK_ERROR_CODE(current_xct.on_record_read(false, &record_batch[i]->owner_id_));
736  }
737  }
739  }
740  for (uint8_t i = 0; i < batch_size; ++i) {
741  payload_batch[i] = record_batch[i]->payload_;
742  }
743  return kErrorCodeOk;
744 }
ErrorCode locate_record_for_read_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **out_batch, bool *snapshot_page_batch)
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
void memory_fence_consume()
Equivalent to std::atomic_thread_fence(std::memory_order_consume).
No guarantee at all for reads, for the sake of best performance and scalability.
Definition: xct_id.hpp:65
#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:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::get_record_primitive ( thread::Thread context,
ArrayOffset  offset,
T *  payload,
uint16_t  payload_offset 
)

Definition at line 388 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), get_payload_size(), foedus::kErrorCodeOk, locate_record_for_read(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, and foedus::storage::Record::payload_.

Referenced by foedus::storage::array::ArrayStorage::get_record_primitive().

392  {
393  ASSERT_ND(payload_offset + sizeof(T) <= get_payload_size());
394  Record *record = nullptr;
395  bool snapshot_record;
396  CHECK_ERROR_CODE(locate_record_for_read(context, offset, &record, &snapshot_record));
397  CHECK_ERROR_CODE(context->get_current_xct().on_record_read(false, &record->owner_id_));
398  char* ptr = record->payload_ + payload_offset;
399  *payload = *reinterpret_cast<const T*>(ptr);
400  return kErrorCodeOk;
401 }
ErrorCode locate_record_for_read(thread::Thread *context, ArrayOffset offset, Record **out, bool *snapshot_record) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::get_record_primitive_batch ( thread::Thread context,
uint16_t  payload_offset,
uint16_t  batch_size,
const ArrayOffset offset_batch,
T *  payload_batch 
)
inline

Definition at line 678 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), foedus::xct::Xct::get_isolation_level(), kBatchMax, foedus::xct::kDirtyRead, foedus::kErrorCodeOk, foedus::storage::kRecordOverhead, locate_record_for_read_batch(), foedus::assorted::memory_fence_consume(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, foedus::storage::Record::payload_, and foedus::assorted::prefetch_cacheline().

Referenced by foedus::storage::array::ArrayStorage::get_record_primitive_batch().

683  {
684  ASSERT_ND(batch_size <= kBatchMax);
685  Record* record_batch[kBatchMax];
686  bool snapshot_record_batch[kBatchMax];
688  context,
689  batch_size,
690  offset_batch,
691  record_batch,
692  snapshot_record_batch));
693  xct::Xct& current_xct = context->get_current_xct();
694  if (current_xct.get_isolation_level() != xct::kDirtyRead) {
695  for (uint8_t i = 0; i < batch_size; ++i) {
696  if (!snapshot_record_batch[i]) {
697  CHECK_ERROR_CODE(current_xct.on_record_read(false, &record_batch[i]->owner_id_));
698  }
699  }
701  }
702  // we anyway prefetched the first 64 bytes. if the column is not within there,
703  // let's do parallel prefetch
704  if (payload_offset + sizeof(T) + kRecordOverhead > 64) {
705  for (uint8_t i = 0; i < batch_size; ++i) {
706  assorted::prefetch_cacheline(record_batch[i]->payload_ + payload_offset);
707  }
708  }
709  for (uint8_t i = 0; i < batch_size; ++i) {
710  char* ptr = record_batch[i]->payload_ + payload_offset;
711  payload_batch[i] = *reinterpret_cast<const T*>(ptr);
712  }
713  return kErrorCodeOk;
714 }
ErrorCode locate_record_for_read_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **out_batch, bool *snapshot_page_batch)
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
void prefetch_cacheline(const void *address)
Prefetch one cacheline to L1 cache.
Definition: cacheline.hpp:49
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
void memory_fence_consume()
Equivalent to std::atomic_thread_fence(std::memory_order_consume).
No guarantee at all for reads, for the sake of best performance and scalability.
Definition: xct_id.hpp:65
#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::array::ArrayStoragePimpl::get_root_page ( thread::Thread context,
bool  for_write,
ArrayPage **  out 
)
inline

Definition at line 337 of file array_storage_pimpl.hpp.

References control_block_, foedus::thread::Thread::follow_page_pointer(), and foedus::storage::array::ArrayStorageControlBlock::root_page_pointer_.

Referenced by lookup_for_read(), lookup_for_read_batch(), lookup_for_write(), lookup_for_write_batch(), prefetch_pages(), and verify_single_thread().

340  {
341  return context->follow_page_pointer(
342  nullptr,
343  false,
344  for_write,
345  true,
347  reinterpret_cast<Page**>(out),
348  nullptr,
349  0);
350 }
DualPagePointer root_page_pointer_
Points to the root page (or something equivalent).
ArrayStorageControlBlock *const control_block_

Here is the call graph for this function:

Here is the caller graph for this function:

uint16_t foedus::storage::array::ArrayStoragePimpl::get_snapshot_drop_volatile_pages_threshold ( ) const
inline

Definition at line 113 of file array_storage_pimpl.hpp.

References get_meta(), and foedus::storage::array::ArrayMetadata::snapshot_drop_volatile_pages_threshold_.

113  {
115  }
uint16_t snapshot_drop_volatile_pages_threshold_
Number of levels of volatile pages to keep after each snapshotting.

Here is the call graph for this function:

ErrorStack foedus::storage::array::ArrayStoragePimpl::hcc_reset_all_temperature_stat ( )

Definition at line 969 of file array_storage_pimpl.cpp.

References CHECK_ERROR, control_block_, engine_, hcc_reset_all_temperature_stat_intermediate(), foedus::storage::VolatilePagePointer::is_null(), foedus::kRetOk, foedus::storage::array::ArrayStorageControlBlock::root_page_pointer_, and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by foedus::storage::array::ArrayStorage::hcc_reset_all_temperature_stat().

969  {
970  LOG(INFO) << "**"
971  << std::endl << "***************************************************************"
972  << std::endl << "*** Reseting " << ArrayStorage(engine_, control_block_) << "'s "
973  << std::endl << "*** temperature stat for HCC"
974  << std::endl << "***************************************************************";
975 
976  DualPagePointer pointer = control_block_->root_page_pointer_;
977  if (pointer.volatile_pointer_.is_null()) {
978  LOG(INFO) << "No volatile pages.";
979  } else {
980  CHECK_ERROR(hcc_reset_all_temperature_stat_intermediate(pointer.volatile_pointer_));
981  }
982 
983  LOG(INFO) << "Done resettting";
984  return kRetOk;
985 }
DualPagePointer root_page_pointer_
Points to the root page (or something equivalent).
ArrayStorageControlBlock *const control_block_
ErrorStack hcc_reset_all_temperature_stat_intermediate(VolatilePagePointer intermediate_page_id)
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
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:

ErrorStack foedus::storage::array::ArrayStoragePimpl::hcc_reset_all_temperature_stat_intermediate ( VolatilePagePointer  intermediate_page_id)

Definition at line 987 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR, engine_, foedus::memory::EngineMemory::get_global_volatile_page_resolver(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_level(), foedus::Engine::get_memory_manager(), foedus::storage::array::ArrayPage::header(), foedus::storage::PageHeader::hotness_, foedus::storage::array::ArrayPage::is_leaf(), foedus::storage::VolatilePagePointer::is_null(), foedus::storage::array::kInteriorFanout, foedus::kRetOk, foedus::assorted::ProbCounter::reset(), and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by hcc_reset_all_temperature_stat().

988  {
989  const auto& resolver = engine_->get_memory_manager()->get_global_volatile_page_resolver();
990  ArrayPage* page = reinterpret_cast<ArrayPage*>(resolver.resolve_offset(intermediate_page_id));
991  ASSERT_ND(page);
992  ASSERT_ND(!page->is_leaf());
993  const bool bottom = page->get_level() == 1U;
994  for (uint8_t i = 0; i < kInteriorFanout; ++i) {
995  VolatilePagePointer page_id = page->get_interior_record(i).volatile_pointer_;
996  if (page_id.is_null()) {
997  continue;
998  }
999  if (bottom) {
1000  ArrayPage* leaf = reinterpret_cast<ArrayPage*>(resolver.resolve_offset(page_id));
1001  leaf->header().hotness_.reset();
1002  } else {
1004  }
1005  }
1006 
1007  return kRetOk;
1008 }
const GlobalVolatilePageResolver & get_global_volatile_page_resolver() const
Returns the page resolver to convert volatile page ID to page pointer.
ErrorStack hcc_reset_all_temperature_stat_intermediate(VolatilePagePointer intermediate_page_id)
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110
#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
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50

Here is the call graph for this function:

Here is the caller graph for this function:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::increment_record ( thread::Thread context,
ArrayOffset  offset,
T *  value,
uint16_t  payload_offset 
)

Definition at line 486 of file array_storage_pimpl.cpp.

References foedus::xct::Xct::add_to_write_set(), ASSERT_ND, foedus::storage::array::ArrayOverwriteLogType::calculate_log_length(), CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), get_id(), get_payload_size(), foedus::thread::Thread::get_thread_log_buffer(), locate_record_for_write(), foedus::xct::Xct::on_record_read(), foedus::storage::Record::owner_id_, foedus::storage::Record::payload_, foedus::storage::array::ArrayOverwriteLogType::populate_primitive(), and foedus::log::ThreadLogBuffer::reserve_new_log().

Referenced by foedus::storage::array::ArrayStorage::increment_record().

487  {
488  ASSERT_ND(payload_offset + sizeof(T) <= get_payload_size());
489  Record *record = nullptr;
490  CHECK_ERROR_CODE(locate_record_for_write(context, offset, &record));
491 
492  // this is get_record + overwrite_record
493  // NOTE This version is like other storage's increment implementation.
494  // Taking read-set (and potentially locks), read the value, then remember the overwrite log.
495  // However the increment_record_oneshot() below is pretty different.
496  CHECK_ERROR_CODE(context->get_current_xct().on_record_read(true, &record->owner_id_));
497  char* ptr = record->payload_ + payload_offset;
498  T tmp = *reinterpret_cast<const T*>(ptr);
499  *value += tmp;
500  uint16_t log_length = ArrayOverwriteLogType::calculate_log_length(sizeof(T));
501  ArrayOverwriteLogType* log_entry = reinterpret_cast<ArrayOverwriteLogType*>(
502  context->get_thread_log_buffer().reserve_new_log(log_length));
503  log_entry->populate_primitive<T>(get_id(), offset, *value, payload_offset);
504  return context->get_current_xct().add_to_write_set(
505  get_id(),
506  &record->owner_id_,
507  record->payload_,
508  log_entry);
509 }
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
static uint16_t calculate_log_length(uint16_t payload_count) __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::increment_record_oneshot ( thread::Thread context,
ArrayOffset  offset,
value,
uint16_t  payload_offset 
)

Definition at line 512 of file array_storage_pimpl.cpp.

References foedus::xct::Xct::add_to_write_set(), ASSERT_ND, foedus::storage::array::ArrayIncrementLogType::calculate_log_length(), CHECK_ERROR_CODE, foedus::thread::Thread::get_current_xct(), get_id(), get_payload_size(), foedus::thread::Thread::get_thread_log_buffer(), locate_record_for_write(), foedus::storage::Record::owner_id_, foedus::storage::Record::payload_, foedus::storage::array::ArrayIncrementLogType::populate(), and foedus::log::ThreadLogBuffer::reserve_new_log().

Referenced by foedus::storage::array::ArrayStorage::increment_record_oneshot().

516  {
517  ASSERT_ND(payload_offset + sizeof(T) <= get_payload_size());
518  Record *record = nullptr;
519  CHECK_ERROR_CODE(locate_record_for_write(context, offset, &record));
520  // Only Array's increment can be the rare "write-set only" log.
521  // other increments have to check deletion bit at least.
522  // To make use of it, we do have array increment log with primitive type as parameter.
523  ValueType type = to_value_type<T>();
524  uint16_t log_length = ArrayIncrementLogType::calculate_log_length(type);
525  ArrayIncrementLogType* log_entry = reinterpret_cast<ArrayIncrementLogType*>(
526  context->get_thread_log_buffer().reserve_new_log(log_length));
527  log_entry->populate<T>(get_id(), offset, value, payload_offset);
528  return context->get_current_xct().add_to_write_set(
529  get_id(),
530  &record->owner_id_,
531  record->payload_,
532  log_entry);
533 }
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
static uint16_t calculate_log_length(ValueType value_type) __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
ValueType
Used in ArrayIncrementLogType.
#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:

ErrorStack foedus::storage::array::ArrayStoragePimpl::load ( const StorageControlBlock snapshot_block)

Definition at line 301 of file array_storage_pimpl.cpp.

References ASSERT_ND, foedus::storage::array::calculate_levels(), CHECK_ERROR, control_block_, engine_, foedus::Engine::get_memory_manager(), get_meta(), get_payload_size(), foedus::DefaultInitializable::initialize(), foedus::storage::kExists, foedus::kRetOk, foedus::UninitializeGuard::kWarnIfUninitializeError, foedus::storage::array::ArrayStorageControlBlock::levels_, load_empty(), foedus::memory::EngineMemory::load_one_volatile_page(), foedus::storage::array::ArrayStorageControlBlock::meta_, foedus::storage::StorageControlBlock::meta_, foedus::storage::array::ArrayStorageControlBlock::root_page_pointer_, foedus::storage::Metadata::root_snapshot_page_id_, foedus::storage::array::ArrayStorageControlBlock::route_finder_, foedus::storage::DualPagePointer::snapshot_pointer_, foedus::storage::array::ArrayStorageControlBlock::status_, foedus::DefaultInitializable::uninitialize(), foedus::storage::DualPagePointer::volatile_pointer_, and foedus::storage::VolatilePagePointer::word.

Referenced by foedus::storage::array::ArrayStorage::load().

301  {
302  control_block_->meta_ = static_cast<const ArrayMetadata&>(snapshot_block.meta_);
303  const ArrayMetadata& meta = control_block_->meta_;
304  ASSERT_ND(meta.root_snapshot_page_id_ != 0);
305  const uint16_t levels = calculate_levels(meta);
306  control_block_->levels_ = levels;
307  control_block_->route_finder_ = LookupRouteFinder(levels, get_payload_size());
308  control_block_->root_page_pointer_.snapshot_pointer_ = meta.root_snapshot_page_id_;
310 
311  // So far we assume the root page always has a volatile version.
312  // Create it now.
313  if (meta.root_snapshot_page_id_ != 0) {
314  cache::SnapshotFileSet fileset(engine_);
315  CHECK_ERROR(fileset.initialize());
316  UninitializeGuard fileset_guard(&fileset, UninitializeGuard::kWarnIfUninitializeError);
317  VolatilePagePointer volatile_pointer;
318  Page* volatile_root;
320  &fileset,
321  meta.root_snapshot_page_id_,
322  &volatile_pointer,
323  &volatile_root));
325  CHECK_ERROR(fileset.uninitialize());
326  } else {
327  LOG(INFO) << "Loading an empty array-storage-" << get_meta();
329  }
330 
332  LOG(INFO) << "Loaded an array-storage-" << get_meta();
333  return kRetOk;
334 }
StorageStatus status_
Status of the storage.
Automatically calls if uninitialize() wasn't called when it gets out of scope, and just complains whe...
ErrorStack load_one_volatile_page(cache::SnapshotFileSet *fileset, storage::SnapshotPagePointer snapshot_pointer, storage::VolatilePagePointer *pointer, storage::Page **page)
Another convenience method that also reads an existing snapshot page to the volatile page...
The storage has been created and ready for use.
Definition: storage_id.hpp:158
DualPagePointer root_page_pointer_
Points to the root page (or something equivalent).
VolatilePagePointer volatile_pointer_
Definition: storage_id.hpp:308
ArrayMetadata meta_
metadata of this storage.
ArrayStorageControlBlock *const control_block_
SnapshotPagePointer snapshot_pointer_
Definition: storage_id.hpp:307
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
uint8_t calculate_levels(const ArrayMetadata &metadata)
#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
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::storage::array::ArrayStoragePimpl::load_empty ( )

Definition at line 254 of file array_storage_pimpl.cpp.

References foedus::storage::array::ArrayMetadata::array_size_, foedus::storage::array::calculate_levels(), CHECK_ERROR, control_block_, engine_, ERROR_STACK, get_id(), foedus::savepoint::SavepointManager::get_initial_current_epoch(), foedus::Engine::get_memory_manager(), foedus::storage::array::LookupRouteFinder::get_records_in_leaf(), foedus::Engine::get_savepoint_manager(), foedus::memory::EngineMemory::grab_one_volatile_page(), foedus::storage::array::ArrayPage::initialize_volatile_page(), foedus::storage::array::ArrayStorageControlBlock::intervals_, foedus::kErrorCodeStrTooLargeArray, foedus::storage::array::kInteriorFanout, foedus::storage::array::kMaxArrayOffset, foedus::kRetOk, foedus::storage::array::ArrayStorageControlBlock::levels_, foedus::storage::array::ArrayStorageControlBlock::meta_, foedus::storage::array::ArrayMetadata::payload_size_, foedus::storage::array::ArrayStorageControlBlock::root_page_pointer_, foedus::storage::Metadata::root_snapshot_page_id_, foedus::storage::array::ArrayStorageControlBlock::route_finder_, foedus::storage::DualPagePointer::snapshot_pointer_, foedus::storage::DualPagePointer::volatile_pointer_, and foedus::storage::VolatilePagePointer::word.

Referenced by create(), and load().

254  {
255  const uint16_t levels = calculate_levels(control_block_->meta_);
256  const uint32_t payload_size = control_block_->meta_.payload_size_;
257  const ArrayOffset array_size = control_block_->meta_.array_size_;
258  if (array_size > kMaxArrayOffset) {
260  }
261  control_block_->levels_ = levels;
262  control_block_->route_finder_ = LookupRouteFinder(levels, payload_size);
267  for (uint16_t level = 1; level < levels; ++level) {
269  }
270 
271  VolatilePagePointer volatile_pointer;
272  ArrayPage* volatile_root;
274  0,
275  &volatile_pointer,
276  reinterpret_cast<Page**>(&volatile_root)));
277  volatile_root->initialize_volatile_page(
278  engine_->get_savepoint_manager()->get_initial_current_epoch(), // lowest epoch in the system
279  get_id(),
280  volatile_pointer,
281  payload_size,
282  levels - 1U,
283  ArrayRange(0, array_size));
285  return kRetOk;
286 }
0x0826 : "STORAGE: Too large array size specified. The size of an array storage must be smaller than ...
Definition: error_code.hpp:189
ArrayOffset array_size_
Size of this array.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
const ArrayOffset kMaxArrayOffset
The maximum value allowed for ArrayOffset.
Definition: array_id.hpp:54
uint64_t intervals_[8]
intervals_[x] is the range of array offset in one page of level-x.
uint64_t ArrayOffset
The only key type in array storage.
Definition: array_id.hpp:48
savepoint::SavepointManager * get_savepoint_manager() const
See Savepoint Manager.
Definition: engine.cpp:53
DualPagePointer root_page_pointer_
Points to the root page (or something equivalent).
VolatilePagePointer volatile_pointer_
Definition: storage_id.hpp:308
ArrayMetadata meta_
metadata of this storage.
ArrayStorageControlBlock *const control_block_
SnapshotPagePointer snapshot_pointer_
Definition: storage_id.hpp:307
ErrorStack grab_one_volatile_page(foedus::thread::ThreadGroupId node, storage::VolatilePagePointer *pointer, storage::Page **page)
A convenience function to grab one free volatile page from the given node.
uint16_t get_records_in_leaf() const __attribute__((always_inline))
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
uint8_t calculate_levels(const ArrayMetadata &metadata)
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110
uint16_t payload_size_
byte size of one record in this array storage without internal overheads
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50
SnapshotPagePointer root_snapshot_page_id_
Pointer to a snapshotted page this storage is rooted at.
Definition: metadata.hpp:112

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::locate_record_for_read ( thread::Thread context,
ArrayOffset  offset,
Record **  out,
bool *  snapshot_record 
)
inline

Definition at line 337 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::storage::array::ArrayRange::contains(), exists(), foedus::storage::array::ArrayPage::get_array_range(), get_array_size(), foedus::storage::array::ArrayPage::get_leaf_record(), get_payload_size(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), foedus::kErrorCodeOk, lookup_for_read(), foedus::storage::Record::owner_id_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by get_record(), get_record_payload(), and get_record_primitive().

341  {
342  ASSERT_ND(exists());
343  ASSERT_ND(offset < get_array_size());
344  uint16_t index = 0;
345  ArrayPage* page = nullptr;
346  CHECK_ERROR_CODE(lookup_for_read(context, offset, &page, &index, snapshot_record));
347  ASSERT_ND(page);
348  ASSERT_ND(page->is_leaf());
349  ASSERT_ND(page->get_array_range().contains(offset));
350  ASSERT_ND(page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_.is_valid());
351  *out = page->get_leaf_record(index, get_payload_size());
352  return kErrorCodeOk;
353 }
0 means no-error.
Definition: error_code.hpp:87
ErrorCode lookup_for_read(thread::Thread *context, ArrayOffset offset, ArrayPage **out, uint16_t *index, bool *snapshot_page) __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::locate_record_for_read_batch ( thread::Thread context,
uint16_t  batch_size,
const ArrayOffset offset_batch,
Record **  out_batch,
bool *  snapshot_page_batch 
)
inline

Definition at line 767 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::storage::array::ArrayPage::get_leaf_record(), get_payload_size(), kBatchMax, foedus::kErrorCodeOk, and lookup_for_read_batch().

Referenced by get_record_payload_batch(), and get_record_primitive_batch().

772  {
773  ASSERT_ND(batch_size <= kBatchMax);
774  ArrayPage* page_batch[kBatchMax];
775  uint16_t index_batch[kBatchMax];
777  context,
778  batch_size,
779  offset_batch,
780  page_batch,
781  index_batch,
782  snapshot_page_batch));
783  const uint16_t payload_size = get_payload_size();
784  for (uint8_t i = 0; i < batch_size; ++i) {
785  ASSERT_ND(page_batch[i]);
786  ASSERT_ND(page_batch[i]->is_leaf());
787  ASSERT_ND(page_batch[i]->get_array_range().contains(offset_batch[i]));
788  out_batch[i] = page_batch[i]->get_leaf_record(index_batch[i], payload_size);
789  ASSERT_ND(out_batch[i]->owner_id_.xct_id_.is_valid());
790  }
791  return kErrorCodeOk;
792 }
ErrorCode lookup_for_read_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, ArrayPage **out_batch, uint16_t *index_batch, bool *snapshot_page_batch)
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::locate_record_for_write ( thread::Thread context,
ArrayOffset  offset,
Record **  out 
)
inline

Definition at line 355 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::storage::array::ArrayRange::contains(), exists(), foedus::storage::array::ArrayPage::get_array_range(), get_array_size(), foedus::storage::array::ArrayPage::get_leaf_record(), get_payload_size(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), foedus::kErrorCodeOk, lookup_for_write(), foedus::storage::Record::owner_id_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by get_record_for_write(), increment_record(), increment_record_oneshot(), overwrite_record(), and overwrite_record_primitive().

358  {
359  ASSERT_ND(exists());
360  ASSERT_ND(offset < get_array_size());
361  uint16_t index = 0;
362  ArrayPage* page = nullptr;
363  CHECK_ERROR_CODE(lookup_for_write(context, offset, &page, &index));
364  ASSERT_ND(page);
365  ASSERT_ND(page->is_leaf());
366  ASSERT_ND(page->get_array_range().contains(offset));
367  ASSERT_ND(page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_.is_valid());
368  *out = page->get_leaf_record(index, get_payload_size());
369  return kErrorCodeOk;
370 }
ErrorCode lookup_for_write(thread::Thread *context, ArrayOffset offset, ArrayPage **out, uint16_t *index) __attribute__((always_inline))
This version always returns a volatile page, installing a new one if needed.
0 means no-error.
Definition: error_code.hpp:87
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::lookup_for_read ( thread::Thread context,
ArrayOffset  offset,
ArrayPage **  out,
uint16_t *  index,
bool *  snapshot_page 
)
inline

Definition at line 535 of file array_storage_pimpl.cpp.

References ASSERT_ND, foedus::storage::array::ArrayRange::begin_, CHECK_ERROR_CODE, foedus::storage::array::ArrayRange::contains(), control_block_, exists(), foedus::storage::array::LookupRouteFinder::find_route(), follow_pointer(), foedus::storage::array::ArrayPage::get_array_range(), get_array_size(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), get_levels(), get_payload_size(), get_root_page(), foedus::storage::array::ArrayPage::header(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), foedus::kErrorCodeOk, foedus::storage::Record::owner_id_, foedus::storage::array::ArrayStorageControlBlock::route_finder_, foedus::storage::PageHeader::snapshot_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by locate_record_for_read().

540  {
541  ASSERT_ND(exists());
542  ASSERT_ND(offset < get_array_size());
543  ASSERT_ND(out);
544  ASSERT_ND(index);
545  ArrayPage* current_page;
546  CHECK_ERROR_CODE(get_root_page(context, false, &current_page));
547  uint16_t levels = get_levels();
548  ASSERT_ND(current_page->get_array_range().contains(offset));
549  LookupRoute route = control_block_->route_finder_.find_route(offset);
550  bool in_snapshot = current_page->header().snapshot_;
551  for (uint8_t level = levels - 1; level > 0; --level) {
552  ASSERT_ND(current_page->get_array_range().contains(offset));
553  DualPagePointer& pointer = current_page->get_interior_record(route.route[level]);
555  context,
556  in_snapshot,
557  false,
558  &pointer,
559  &current_page,
560  current_page,
561  route.route[level]));
562  in_snapshot = current_page->header().snapshot_;
563  }
564  ASSERT_ND(current_page->is_leaf());
565  ASSERT_ND(current_page->get_array_range().contains(offset));
566  ASSERT_ND(current_page->get_array_range().begin_ + route.route[0] == offset);
567  ASSERT_ND(current_page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_.is_valid());
568  *out = current_page;
569  *index = route.route[0];
570  *snapshot_page = (*out)->header().snapshot_;
571  return kErrorCodeOk;
572 }
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
ArrayStorageControlBlock *const control_block_
LookupRoute find_route(ArrayOffset offset) const __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
ErrorCode follow_pointer(thread::Thread *context, bool in_snapshot, bool for_write, DualPagePointer *pointer, ArrayPage **out, const ArrayPage *parent, uint16_t index_in_parent) __attribute__((always_inline))
#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::array::ArrayStoragePimpl::lookup_for_read_batch ( thread::Thread context,
uint16_t  batch_size,
const ArrayOffset offset_batch,
ArrayPage **  out_batch,
uint16_t *  index_batch,
bool *  snapshot_page_batch 
)
inline

Definition at line 794 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::storage::construct_volatile_page_pointer(), control_block_, foedus::storage::extract_local_page_id_from_snapshot_pointer(), foedus::storage::array::LookupRouteFinder::find_route(), follow_pointers_for_read_batch(), get_array_size(), get_id(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), get_levels(), get_payload_size(), get_root_page(), foedus::storage::array::ArrayPage::header(), kBatchMax, foedus::kErrorCodeOk, foedus::assorted::prefetch_cacheline(), foedus::storage::array::LookupRoute::route, foedus::storage::array::ArrayStorageControlBlock::route_finder_, and foedus::storage::PageHeader::snapshot_.

Referenced by locate_record_for_read_batch().

800  {
801  ASSERT_ND(batch_size <= kBatchMax);
802  LookupRoute routes[kBatchMax];
803  ArrayPage* root_page;
804  CHECK_ERROR_CODE(get_root_page(context, false, &root_page));
805  uint16_t levels = get_levels();
806  bool root_snapshot = root_page->header().snapshot_;
807  const uint16_t payload_size = get_payload_size();
808  for (uint8_t i = 0; i < batch_size; ++i) {
809  ASSERT_ND(offset_batch[i] < get_array_size());
810  routes[i] = control_block_->route_finder_.find_route(offset_batch[i]);
811  if (levels <= 1U) {
812  assorted::prefetch_cacheline(root_page->get_leaf_record(
813  routes[i].route[0],
814  payload_size));
815  } else {
816  assorted::prefetch_cacheline(&root_page->get_interior_record(routes[i].route[levels - 1]));
817  }
818  out_batch[i] = root_page;
819  snapshot_page_batch[i] = root_snapshot;
820  ASSERT_ND(out_batch[i]->get_array_range().contains(offset_batch[i]));
821  index_batch[i] = routes[i].route[levels - 1];
822  }
823 
824  for (uint8_t level = levels - 1; level > 0; --level) {
825  // note that we use out_batch as both input (parents) and output (the pages) here.
826  // the method works in that case too.
828  context,
829  batch_size,
830  snapshot_page_batch,
831  out_batch,
832  index_batch,
833  out_batch));
834 
835  for (uint8_t i = 0; i < batch_size; ++i) {
836  ASSERT_ND(snapshot_page_batch[i] == out_batch[i]->header().snapshot_);
837  ASSERT_ND(out_batch[i]->get_storage_id() == get_id());
838  ASSERT_ND(snapshot_page_batch[i]
839  || !construct_volatile_page_pointer(out_batch[i]->header().page_id_).is_null());
840  ASSERT_ND(!snapshot_page_batch[i]
841  || extract_local_page_id_from_snapshot_pointer(out_batch[i]->header().page_id_));
842  if (level == 1U) {
843  assorted::prefetch_cacheline(out_batch[i]->get_leaf_record(
844  routes[i].route[0],
845  payload_size));
846  } else {
848  &out_batch[i]->get_interior_record(routes[i].route[levels - 1]));
849  }
850  index_batch[i] = routes[i].route[level - 1];
851  }
852  }
853  for (uint8_t i = 0; i < batch_size; ++i) {
854  ASSERT_ND(out_batch[i]->is_leaf());
855  ASSERT_ND(out_batch[i]->get_array_range().contains(offset_batch[i]));
856  ASSERT_ND(out_batch[i]->get_array_range().begin_ + routes[i].route[0] == offset_batch[i]);
857  ASSERT_ND(index_batch[i] == routes[i].route[0]);
858  ASSERT_ND(
859  out_batch[i]->get_leaf_record(index_batch[i], payload_size)->owner_id_.xct_id_.is_valid());
860  }
861  return kErrorCodeOk;
862 }
SnapshotLocalPageId extract_local_page_id_from_snapshot_pointer(SnapshotPagePointer pointer)
Definition: storage_id.hpp:91
void prefetch_cacheline(const void *address)
Prefetch one cacheline to L1 cache.
Definition: cacheline.hpp:49
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
ArrayStorageControlBlock *const control_block_
LookupRoute find_route(ArrayOffset offset) const __attribute__((always_inline))
ErrorCode follow_pointers_for_read_batch(thread::Thread *context, uint16_t batch_size, bool *in_snapshot, ArrayPage **parents, const uint16_t *index_in_parents, ArrayPage **out)
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
VolatilePagePointer construct_volatile_page_pointer(uint64_t word)
Definition: storage_id.hpp:230
#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::array::ArrayStoragePimpl::lookup_for_write ( thread::Thread context,
ArrayOffset  offset,
ArrayPage **  out,
uint16_t *  index 
)
inline

This version always returns a volatile page, installing a new one if needed.

Definition at line 574 of file array_storage_pimpl.cpp.

References ASSERT_ND, foedus::storage::array::ArrayRange::begin_, CHECK_ERROR_CODE, foedus::storage::array::ArrayRange::contains(), control_block_, exists(), foedus::storage::array::LookupRouteFinder::find_route(), follow_pointer(), foedus::storage::array::ArrayPage::get_array_range(), get_array_size(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), get_levels(), get_payload_size(), get_root_page(), foedus::storage::array::ArrayPage::header(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::XctId::is_valid(), foedus::kErrorCodeOk, foedus::storage::Record::owner_id_, foedus::storage::array::ArrayStorageControlBlock::route_finder_, foedus::storage::PageHeader::snapshot_, and foedus::xct::RwLockableXctId::xct_id_.

Referenced by locate_record_for_write().

578  {
579  ASSERT_ND(exists());
580  ASSERT_ND(offset < get_array_size());
581  ASSERT_ND(out);
582  ASSERT_ND(index);
583  ArrayPage* current_page;
584  CHECK_ERROR_CODE(get_root_page(context, true, &current_page));
585  ASSERT_ND(!current_page->header().snapshot_);
586  uint16_t levels = get_levels();
587  ASSERT_ND(current_page->get_array_range().contains(offset));
588  LookupRoute route = control_block_->route_finder_.find_route(offset);
589  for (uint8_t level = levels - 1; level > 0; --level) {
590  ASSERT_ND(current_page->get_array_range().contains(offset));
592  context,
593  false,
594  true,
595  &current_page->get_interior_record(route.route[level]),
596  &current_page,
597  current_page,
598  route.route[level]));
599  }
600  ASSERT_ND(current_page->is_leaf());
601  ASSERT_ND(current_page->get_array_range().contains(offset));
602  ASSERT_ND(current_page->get_array_range().begin_ + route.route[0] == offset);
603  ASSERT_ND(current_page->get_leaf_record(0, get_payload_size())->owner_id_.xct_id_.is_valid());
604  *out = current_page;
605  *index = route.route[0];
606  return kErrorCodeOk;
607 }
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
ArrayStorageControlBlock *const control_block_
LookupRoute find_route(ArrayOffset offset) const __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
ErrorCode follow_pointer(thread::Thread *context, bool in_snapshot, bool for_write, DualPagePointer *pointer, ArrayPage **out, const ArrayPage *parent, uint16_t index_in_parent) __attribute__((always_inline))
#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::array::ArrayStoragePimpl::lookup_for_write_batch ( thread::Thread context,
uint16_t  batch_size,
const ArrayOffset offset_batch,
Record **  record_batch 
)
inline

Definition at line 864 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, foedus::storage::construct_volatile_page_pointer(), control_block_, foedus::storage::array::LookupRouteFinder::find_route(), follow_pointers_for_write_batch(), get_array_size(), get_id(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), get_levels(), get_payload_size(), get_root_page(), foedus::storage::array::ArrayPage::header(), kBatchMax, foedus::kErrorCodeOk, foedus::assorted::prefetch_cacheline(), foedus::storage::array::LookupRoute::route, foedus::storage::array::ArrayStorageControlBlock::route_finder_, and foedus::storage::PageHeader::snapshot_.

Referenced by get_record_for_write_batch().

868  {
869  ASSERT_ND(batch_size <= kBatchMax);
870  ArrayPage* pages[kBatchMax];
871  LookupRoute routes[kBatchMax];
872  uint16_t index_batch[kBatchMax];
873  ArrayPage* root_page;
874  CHECK_ERROR_CODE(get_root_page(context, true, &root_page));
875  ASSERT_ND(!root_page->header().snapshot_);
876  uint16_t levels = get_levels();
877  const uint16_t payload_size = get_payload_size();
878 
879  for (uint8_t i = 0; i < batch_size; ++i) {
880  ASSERT_ND(offset_batch[i] < get_array_size());
881  routes[i] = control_block_->route_finder_.find_route(offset_batch[i]);
882  if (levels <= 1U) {
883  assorted::prefetch_cacheline(root_page->get_leaf_record(
884  routes[i].route[0],
885  payload_size));
886  } else {
887  assorted::prefetch_cacheline(&root_page->get_interior_record(routes[i].route[levels - 1]));
888  }
889  pages[i] = root_page;
890  ASSERT_ND(pages[i]->get_array_range().contains(offset_batch[i]));
891  index_batch[i] = routes[i].route[levels - 1];
892  }
893 
894  for (uint8_t level = levels - 1; level > 0; --level) {
895  // as noted above, in==out case.
897  context,
898  batch_size,
899  pages,
900  index_batch,
901  pages));
902 
903  for (uint8_t i = 0; i < batch_size; ++i) {
904  ASSERT_ND(!pages[i]->header().snapshot_);
905  ASSERT_ND(pages[i]->get_storage_id() == get_id());
906  ASSERT_ND(!construct_volatile_page_pointer(pages[i]->header().page_id_).is_null());
907  if (level == 1U) {
908  assorted::prefetch_cacheline(pages[i]->get_leaf_record(
909  routes[i].route[0],
910  payload_size));
911  } else {
913  &pages[i]->get_interior_record(routes[i].route[levels - 1]));
914  }
915  index_batch[i] = routes[i].route[level - 1];
916  }
917  }
918 
919  for (uint8_t i = 0; i < batch_size; ++i) {
920  ASSERT_ND(pages[i]->is_leaf());
921  ASSERT_ND(pages[i]->get_array_range().contains(offset_batch[i]));
922  ASSERT_ND(pages[i]->get_array_range().begin_ + routes[i].route[0] == offset_batch[i]);
923  ASSERT_ND(index_batch[i] == routes[i].route[0]);
924  record_batch[i] = pages[i]->get_leaf_record(routes[i].route[0], payload_size);
925  }
926  return kErrorCodeOk;
927 }
ErrorCode follow_pointers_for_write_batch(thread::Thread *context, uint16_t batch_size, ArrayPage **parents, const uint16_t *index_in_parents, ArrayPage **out)
void prefetch_cacheline(const void *address)
Prefetch one cacheline to L1 cache.
Definition: cacheline.hpp:49
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
If you want more than this, you should loop.
0 means no-error.
Definition: error_code.hpp:87
ArrayStorageControlBlock *const control_block_
LookupRoute find_route(ArrayOffset offset) const __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
VolatilePagePointer construct_volatile_page_pointer(uint64_t word)
Definition: storage_id.hpp:230
#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::array::ArrayStoragePimpl::overwrite_record ( thread::Thread context,
ArrayOffset  offset,
const void *  payload,
uint16_t  payload_offset,
uint16_t  payload_count 
)
inline

Definition at line 432 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, get_payload_size(), and locate_record_for_write().

Referenced by foedus::storage::array::ArrayStorage::overwrite_record().

433  {
434  ASSERT_ND(payload_offset + payload_count <= get_payload_size());
435  Record *record = nullptr;
436  CHECK_ERROR_CODE(locate_record_for_write(context, offset, &record));
437  return overwrite_record(context, offset, record, payload, payload_offset, payload_count);
438 }
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
ErrorCode overwrite_record(thread::Thread *context, ArrayOffset offset, const void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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::array::ArrayStoragePimpl::overwrite_record ( thread::Thread context,
ArrayOffset  offset,
Record record,
const void *  payload,
uint16_t  payload_offset,
uint16_t  payload_count 
)
inline

Definition at line 449 of file array_storage_pimpl.cpp.

References foedus::xct::Xct::add_to_write_set(), foedus::storage::array::ArrayOverwriteLogType::calculate_log_length(), foedus::thread::Thread::get_current_xct(), get_id(), foedus::thread::Thread::get_thread_log_buffer(), foedus::storage::Record::owner_id_, foedus::storage::Record::payload_, foedus::storage::array::ArrayOverwriteLogType::populate(), and foedus::log::ThreadLogBuffer::reserve_new_log().

455  {
456  uint16_t log_length = ArrayOverwriteLogType::calculate_log_length(payload_count);
457  ArrayOverwriteLogType* log_entry = reinterpret_cast<ArrayOverwriteLogType*>(
458  context->get_thread_log_buffer().reserve_new_log(log_length));
459  log_entry->populate(get_id(), offset, payload, payload_offset, payload_count);
460  return context->get_current_xct().add_to_write_set(
461  get_id(),
462  &record->owner_id_,
463  record->payload_,
464  log_entry);
465 }
static uint16_t calculate_log_length(uint16_t payload_count) __attribute__((always_inline))

Here is the call graph for this function:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::overwrite_record_primitive ( thread::Thread context,
ArrayOffset  offset,
payload,
uint16_t  payload_offset 
)

Definition at line 441 of file array_storage_pimpl.cpp.

References ASSERT_ND, CHECK_ERROR_CODE, get_payload_size(), and locate_record_for_write().

Referenced by foedus::storage::array::ArrayStorage::overwrite_record_primitive().

442  {
443  ASSERT_ND(payload_offset + sizeof(T) <= get_payload_size());
444  Record *record = nullptr;
445  CHECK_ERROR_CODE(locate_record_for_write(context, offset, &record));
446  return overwrite_record_primitive<T>(context, offset, record, payload, payload_offset);
447 }
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
#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:

template<typename T >
ErrorCode foedus::storage::array::ArrayStoragePimpl::overwrite_record_primitive ( thread::Thread context,
ArrayOffset  offset,
Record record,
payload,
uint16_t  payload_offset 
)
inline

Definition at line 468 of file array_storage_pimpl.cpp.

References foedus::xct::Xct::add_to_write_set(), foedus::storage::array::ArrayOverwriteLogType::calculate_log_length(), foedus::thread::Thread::get_current_xct(), get_id(), foedus::thread::Thread::get_thread_log_buffer(), foedus::storage::Record::owner_id_, foedus::storage::Record::payload_, foedus::storage::array::ArrayOverwriteLogType::populate_primitive(), and foedus::log::ThreadLogBuffer::reserve_new_log().

473  {
474  uint16_t log_length = ArrayOverwriteLogType::calculate_log_length(sizeof(T));
475  ArrayOverwriteLogType* log_entry = reinterpret_cast<ArrayOverwriteLogType*>(
476  context->get_thread_log_buffer().reserve_new_log(log_length));
477  log_entry->populate_primitive<T>(get_id(), offset, payload, payload_offset);
478  return context->get_current_xct().add_to_write_set(
479  get_id(),
480  &record->owner_id_,
481  record->payload_,
482  log_entry);
483 }
static uint16_t calculate_log_length(uint16_t payload_count) __attribute__((always_inline))

Here is the call graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::prefetch_pages ( thread::Thread context,
bool  install_volatile,
bool  cache_snapshot,
ArrayOffset  from,
ArrayOffset  to 
)

defined in array_storage_prefetch.cpp

Definition at line 31 of file array_storage_prefetch.cpp.

References CHECK_ERROR_CODE, foedus::debugging::StopWatch::elapsed_us(), get_meta(), get_root_page(), foedus::thread::Thread::get_thread_id(), foedus::storage::array::ArrayPage::is_leaf(), foedus::kErrorCodeOk, foedus::storage::Metadata::name_, foedus::storage::prefetch_page_l2(), prefetch_pages_recurse(), and foedus::debugging::StopWatch::stop().

Referenced by foedus::storage::array::ArrayStorage::prefetch_pages().

36  {
37  debugging::StopWatch watch;
38  VLOG(0) << "Thread-" << context->get_thread_id()
39  << " prefetching " << get_meta().name_ << " from=" << from << ", to=" << to;
40  ArrayPage* root_page;
41  CHECK_ERROR_CODE(get_root_page(context, vol_on, &root_page));
42  prefetch_page_l2(root_page);
43  if (!root_page->is_leaf()) {
44  CHECK_ERROR_CODE(prefetch_pages_recurse(context, vol_on, snp_on, from, to, root_page));
45  }
46 
47  watch.stop();
48  VLOG(0) << "Thread-" << context->get_thread_id()
49  << " prefetched " << get_meta().name_ << " in " << watch.elapsed_us() << "us";
50  return kErrorCodeOk;
51 }
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
0 means no-error.
Definition: error_code.hpp:87
void prefetch_page_l2(const void *page)
Prefetch a page to L2/L3 cache.
StorageName name_
the unique name of this storage.
Definition: metadata.hpp:107
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
ErrorCode prefetch_pages_recurse(thread::Thread *context, bool install_volatile, bool cache_snapshot, ArrayOffset from, ArrayOffset to, ArrayPage *page)

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorCode foedus::storage::array::ArrayStoragePimpl::prefetch_pages_recurse ( thread::Thread context,
bool  install_volatile,
bool  cache_snapshot,
ArrayOffset  from,
ArrayOffset  to,
ArrayPage page 
)

Definition at line 53 of file array_storage_prefetch.cpp.

References ASSERT_ND, foedus::storage::array::ArrayRange::begin_, CHECK_ERROR_CODE, control_block_, foedus::storage::array::ArrayRange::end_, foedus::thread::Thread::find_or_read_a_snapshot_page(), foedus::storage::array::ArrayPage::get_array_range(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_level(), foedus::storage::array::LookupRouteFinder::get_records_in_leaf(), foedus::storage::array::ArrayPage::header(), foedus::thread::Thread::install_a_volatile_page(), foedus::storage::VolatilePagePointer::is_null(), foedus::kErrorCodeOk, foedus::storage::array::kInteriorFanout, foedus::storage::array::ArrayRange::overlaps(), foedus::storage::prefetch_page_l2(), foedus::thread::Thread::resolve_cast(), foedus::storage::array::ArrayStorageControlBlock::route_finder_, foedus::storage::PageHeader::snapshot_, foedus::storage::DualPagePointer::snapshot_pointer_, and foedus::storage::DualPagePointer::volatile_pointer_.

Referenced by prefetch_pages().

59  {
60  ASSERT_ND(!page->header().snapshot_ || !vol_on);
61  uint8_t level = page->get_level();
62  ASSERT_ND(level > 0);
64  for (uint8_t i = 1; i < level; ++i) {
65  interval *= kInteriorFanout;
66  }
67  bool in_snapshot = page->header().snapshot_;
68  ArrayRange page_range = page->get_array_range();
69  ArrayRange range(from, to);
70  ASSERT_ND(page_range.overlaps(range)); // otherwise why we came here...
71  ASSERT_ND(page_range.begin_ + (interval * kInteriorFanout) >= page_range.end_); // probably==
72  for (uint16_t i = 0; i < kInteriorFanout; ++i) {
73  ArrayRange child_range(
74  page_range.begin_ + i * interval,
75  page_range.begin_ + (i + 1U) * interval);
76  if (!range.overlaps(child_range)) {
77  continue;
78  }
79 
80  DualPagePointer& pointer = page->get_interior_record(i);
81 
82  // first, do we have to cache snapshot page?
83  if (pointer.snapshot_pointer_ != 0) {
84  if (snp_on) {
85  ArrayPage* child;
86  CHECK_ERROR_CODE(context->find_or_read_a_snapshot_page(
87  pointer.snapshot_pointer_,
88  reinterpret_cast<Page**>(&child)));
89  ASSERT_ND(child->get_array_range().begin_ == page_range.begin_ + i * interval);
90  ASSERT_ND(range.overlaps(child->get_array_range()));
91  prefetch_page_l2(child);
92  if (level > 1U) {
93  CHECK_ERROR_CODE(prefetch_pages_recurse(context, false, snp_on, from, to, child));
94  }
95  }
96  // do we have to install volatile page based on it?
97  if (pointer.volatile_pointer_.is_null() && vol_on && !in_snapshot) {
98  ArrayPage* child;
99  CHECK_ERROR_CODE(context->install_a_volatile_page(
100  &pointer,
101  reinterpret_cast<Page**>(&child)));
102  ASSERT_ND(child->get_array_range().begin_ == page_range.begin_ + i * interval);
103  ASSERT_ND(range.overlaps(child->get_array_range()));
104  }
105  }
106 
107  // then go down
108  if (vol_on && !pointer.volatile_pointer_.is_null()) {
109  ASSERT_ND(!in_snapshot);
110  ArrayPage* child = context->resolve_cast<ArrayPage>(pointer.volatile_pointer_);
111  ASSERT_ND(child->get_array_range().begin_ == page_range.begin_ + i * interval);
112  ASSERT_ND(range.overlaps(child->get_array_range()));
113  prefetch_page_l2(child);
114  if (level > 1U) {
115  CHECK_ERROR_CODE(prefetch_pages_recurse(context, vol_on, snp_on, from, to, child));
116  }
117  }
118  }
119  return kErrorCodeOk;
120 }
uint64_t ArrayOffset
The only key type in array storage.
Definition: array_id.hpp:48
0 means no-error.
Definition: error_code.hpp:87
ArrayStorageControlBlock *const control_block_
void prefetch_page_l2(const void *page)
Prefetch a page to L2/L3 cache.
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Definition: error_code.hpp:155
uint16_t get_records_in_leaf() const __attribute__((always_inline))
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110
#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
ErrorCode prefetch_pages_recurse(thread::Thread *context, bool install_volatile, bool cache_snapshot, ArrayOffset from, ArrayOffset to, ArrayPage *page)

Here is the call graph for this function:

Here is the caller graph for this function:

void foedus::storage::array::ArrayStoragePimpl::release_pages_recursive ( const memory::GlobalVolatilePageResolver resolver,
memory::PageReleaseBatch batch,
VolatilePagePointer  volatile_page_id 
)
static

Used only from drop()

Definition at line 207 of file array_storage_pimpl.cpp.

References ASSERT_ND, foedus::storage::VolatilePagePointer::is_null(), foedus::storage::array::kInteriorFanout, foedus::memory::PageReleaseBatch::release(), foedus::memory::GlobalVolatilePageResolver::resolve_offset(), foedus::storage::DualPagePointer::volatile_pointer_, and foedus::storage::VolatilePagePointer::word.

Referenced by foedus::storage::array::ArrayStorage::drop().

210  {
211  ASSERT_ND(!volatile_page_id.is_null());
212  ArrayPage* page = reinterpret_cast<ArrayPage*>(resolver.resolve_offset(volatile_page_id));
213  if (!page->is_leaf()) {
214  for (uint16_t i = 0; i < kInteriorFanout; ++i) {
215  DualPagePointer &child_pointer = page->get_interior_record(i);
216  VolatilePagePointer child_page_id = child_pointer.volatile_pointer_;
217  if (!child_page_id.is_null()) {
218  // then recurse
219  release_pages_recursive(resolver, batch, child_page_id);
220  child_pointer.volatile_pointer_.word = 0;
221  }
222  }
223  }
224  batch->release(volatile_page_id);
225 }
static void release_pages_recursive(const memory::GlobalVolatilePageResolver &resolver, memory::PageReleaseBatch *batch, VolatilePagePointer volatile_page_id)
Used only from drop()
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110
#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::array::ArrayStoragePimpl::report_page_distribution ( )
ErrorStack foedus::storage::array::ArrayStoragePimpl::verify_single_thread ( thread::Thread context)

Definition at line 932 of file array_storage_pimpl.cpp.

References get_root_page(), and WRAP_ERROR_CODE.

Referenced by verify_single_thread(), and foedus::storage::array::ArrayStorage::verify_single_thread().

932  {
933  ArrayPage* root;
934  WRAP_ERROR_CODE(get_root_page(context, false, &root));
935  return verify_single_thread(context, root);
936 }
ErrorStack verify_single_thread(thread::Thread *context)
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
#define WRAP_ERROR_CODE(x)
Same as CHECK_ERROR(x) except it receives only an error code, thus more efficient.

Here is the call graph for this function:

Here is the caller graph for this function:

ErrorStack foedus::storage::array::ArrayStoragePimpl::verify_single_thread ( thread::Thread context,
ArrayPage page 
)

Definition at line 937 of file array_storage_pimpl.cpp.

References CHECK_AND_ASSERT, CHECK_ERROR, foedus::thread::Thread::get_global_volatile_page_resolver(), foedus::storage::array::ArrayPage::get_interior_record(), foedus::storage::array::ArrayPage::get_leaf_record(), foedus::storage::array::ArrayPage::get_leaf_record_count(), get_payload_size(), foedus::xct::McsRwLock::get_tail_waiter(), foedus::xct::McsRwLock::get_tail_waiter_block(), foedus::xct::RwLockableXctId::is_being_written(), foedus::xct::RwLockableXctId::is_deleted(), foedus::xct::RwLockableXctId::is_keylocked(), foedus::storage::array::ArrayPage::is_leaf(), foedus::xct::RwLockableXctId::is_moved(), foedus::storage::VolatilePagePointer::is_null(), foedus::storage::array::kInteriorFanout, foedus::kRetOk, foedus::xct::RwLockableXctId::lock_, foedus::storage::Record::owner_id_, foedus::memory::GlobalVolatilePageResolver::resolve_offset(), verify_single_thread(), and foedus::storage::DualPagePointer::volatile_pointer_.

937  {
938  const memory::GlobalVolatilePageResolver& resolver = context->get_global_volatile_page_resolver();
939  if (page->is_leaf()) {
940  for (uint16_t i = 0; i < page->get_leaf_record_count(); ++i) {
941  Record* record = page->get_leaf_record(i, get_payload_size());
942  CHECK_AND_ASSERT(!record->owner_id_.is_being_written());
943  CHECK_AND_ASSERT(!record->owner_id_.is_deleted());
944  CHECK_AND_ASSERT(!record->owner_id_.is_keylocked());
945  CHECK_AND_ASSERT(!record->owner_id_.is_moved());
946  CHECK_AND_ASSERT(record->owner_id_.lock_.get_tail_waiter() == 0);
947  CHECK_AND_ASSERT(record->owner_id_.lock_.get_tail_waiter_block() == 0);
948  }
949  } else {
950  for (uint16_t i = 0; i < kInteriorFanout; ++i) {
951  DualPagePointer &child_pointer = page->get_interior_record(i);
952  VolatilePagePointer page_id = child_pointer.volatile_pointer_;
953  if (!page_id.is_null()) {
954  // then recurse
955  ArrayPage* child_page = reinterpret_cast<ArrayPage*>(resolver.resolve_offset(page_id));
956  CHECK_ERROR(verify_single_thread(context, child_page));
957  }
958  }
959  }
960  return kRetOk;
961 }
ErrorStack verify_single_thread(thread::Thread *context)
#define CHECK_AND_ASSERT(x)
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
const ErrorStack kRetOk
Normal return value for no-error case.
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
Definition: array_id.hpp:110

Here is the call graph for this function:

Member Data Documentation

Engine* const foedus::storage::array::ArrayStoragePimpl::engine_

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