20 #include <glog/logging.h>
71 void *payload, uint16_t payload_offset, uint16_t payload_count) {
73 context, offset, payload, payload_offset, payload_count);
78 T *payload, uint16_t payload_offset) {
85 const void **payload) {
97 const void *payload, uint16_t payload_offset, uint16_t payload_count) {
106 template <
typename T>
108 T payload, uint16_t payload_offset) {
121 uint16_t payload_offset,
122 uint16_t payload_count) {
132 template <
typename T>
138 uint16_t payload_offset) {
147 template <
typename T>
149 T* value, uint16_t payload_offset) {
153 template <
typename T>
158 uint16_t payload_offset) {
171 uint64_t array_size, uint16_t payload) {
177 LOG(INFO) <<
"We need " << leaf_pages <<
" leaf pages";
180 uint64_t total_pages = leaf_pages;
181 std::vector<uint64_t> pages;
182 pages.push_back(leaf_pages);
183 while (pages.back() != 1) {
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;
190 LOG(INFO) <<
"In total, we need " << total_pages <<
" pages";
213 if (!page->is_leaf()) {
217 if (!child_page_id.
is_null()) {
224 batch->
release(volatile_page_id);
228 LOG(INFO) <<
"Uninitializing an array-storage " << *
this;
229 if (!
control_block_->root_page_pointer_.volatile_pointer_.is_null()) {
246 std::vector<uint64_t> offset_intervals;
248 for (uint8_t level = 1; level < levels; ++level) {
249 offset_intervals.push_back(offset_intervals[level - 1] *
kInteriorFanout);
251 return offset_intervals;
267 for (uint16_t level = 1; level < levels; ++level) {
276 reinterpret_cast<Page**>(&volatile_root)));
290 LOG(ERROR) <<
"This array-storage already exists-" << metadata.
id_;
295 LOG(INFO) <<
"Newly created an array-storage " << metadata.
id_;
327 LOG(INFO) <<
"Loading an empty array-storage-" <<
get_meta();
332 LOG(INFO) <<
"Loaded an array-storage-" <<
get_meta();
341 bool* snapshot_record) {
376 uint16_t payload_offset,
377 uint16_t payload_count) {
380 bool snapshot_record;
383 std::memcpy(payload, record->
payload_ + payload_offset, payload_count);
387 template <
typename T>
392 uint16_t payload_offset) {
395 bool snapshot_record;
398 char* ptr = record->
payload_ + payload_offset;
399 *payload = *
reinterpret_cast<const T*
>(ptr);
406 const void** payload) {
408 bool snapshot_record;
411 if (!snapshot_record &&
433 const void *payload, uint16_t payload_offset, uint16_t payload_count) {
437 return overwrite_record(context, offset, record, payload, payload_offset, payload_count);
440 template <
typename T>
446 return overwrite_record_primitive<T>(context, offset, record, payload, payload_offset);
454 uint16_t payload_offset,
455 uint16_t payload_count) {
459 log_entry->
populate(
get_id(), offset, payload, payload_offset, payload_count);
467 template <
typename T>
473 uint16_t payload_offset) {
485 template <
typename T>
497 char* ptr = record->
payload_ + payload_offset;
498 T tmp = *
reinterpret_cast<const T*
>(ptr);
511 template <
typename T>
516 uint16_t payload_offset) {
540 bool* snapshot_page) {
551 for (uint8_t level = levels - 1; level > 0; --level) {
561 route.route[level]));
569 *index = route.route[0];
589 for (uint8_t level = levels - 1; level > 0; --level) {
598 route.route[level]));
605 *index = route.route[0];
610 template <
typename T>
613 uint16_t payload_offset,
618 for (uint16_t cur = 0; cur < batch_size;) {
619 uint16_t chunk = batch_size - cur;
628 &payload_batch[cur]));
638 const void** payload_batch) {
640 for (uint16_t cur = 0; cur < batch_size;) {
641 uint16_t chunk = batch_size - cur;
649 &payload_batch[cur]));
661 for (uint16_t cur = 0; cur < batch_size;) {
662 uint16_t chunk = batch_size - cur;
670 &record_batch[cur]));
677 template <
typename T>
680 uint16_t payload_offset,
692 snapshot_record_batch));
695 for (uint8_t i = 0; i < batch_size; ++i) {
696 if (!snapshot_record_batch[i]) {
705 for (uint8_t i = 0; i < batch_size; ++i) {
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);
721 const void** payload_batch) {
730 snapshot_record_batch));
733 for (uint8_t i = 0; i < batch_size; ++i) {
734 if (!snapshot_record_batch[i]) {
740 for (uint8_t i = 0; i < batch_size; ++i) {
741 payload_batch[i] = record_batch[i]->
payload_;
759 for (uint8_t i = 0; i < batch_size; ++i) {
772 bool* snapshot_page_batch) {
782 snapshot_page_batch));
784 for (uint8_t i = 0; i < batch_size; ++i) {
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());
799 uint16_t* index_batch,
800 bool* snapshot_page_batch) {
808 for (uint8_t i = 0; i < batch_size; ++i) {
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];
824 for (uint8_t level = levels - 1; level > 0; --level) {
835 for (uint8_t i = 0; i < batch_size; ++i) {
836 ASSERT_ND(snapshot_page_batch[i] == out_batch[i]->header().snapshot_);
848 &out_batch[i]->get_interior_record(routes[i].route[levels - 1]));
850 index_batch[i] = routes[i].
route[level - 1];
853 for (uint8_t i = 0; i < batch_size; ++i) {
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]);
859 out_batch[i]->get_leaf_record(index_batch[i], payload_size)->owner_id_.xct_id_.is_valid());
879 for (uint8_t i = 0; i < batch_size; ++i) {
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];
894 for (uint8_t level = levels - 1; level > 0; --level) {
903 for (uint8_t i = 0; i < batch_size; ++i) {
904 ASSERT_ND(!pages[i]->header().snapshot_);
913 &pages[i]->get_interior_record(routes[i].route[levels - 1]));
915 index_batch[i] = routes[i].
route[level - 1];
919 for (uint8_t i = 0; i < batch_size; ++i) {
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);
929 #define CHECK_AND_ASSERT(x) do { ASSERT_ND(x); if (!(x)) \
930 return ERROR_STACK(kErrorCodeStrArrayFailedVerification); } while (0)
971 << std::endl <<
"***************************************************************"
973 << std::endl <<
"*** temperature stat for HCC"
974 << std::endl <<
"***************************************************************";
978 LOG(INFO) <<
"No volatile pages.";
983 LOG(INFO) <<
"Done resettting";
990 ArrayPage* page =
reinterpret_cast<ArrayPage*
>(resolver.resolve_offset(intermediate_page_id));
993 const bool bottom = page->
get_level() == 1U;
1012 uint16_t batch_size,
1015 const uint16_t* index_in_parents,
1018 for (uint8_t i = 0; i < batch_size; ++i) {
1020 ASSERT_ND(in_snapshot[i] == parents[i]->header().snapshot_);
1027 for (uint8_t i = 0; i < batch_size; ++i) {
1028 parents_copy[i] = parents[i];
1038 reinterpret_cast<Page**>(parents),
1041 reinterpret_cast<Page**>(out)));
1044 for (uint8_t i = 0; i < batch_size; ++i) {
1077 uint16_t batch_size,
1079 const uint16_t* index_in_parents,
1082 for (uint8_t i = 0; i < batch_size; ++i) {
1084 ASSERT_ND(!parents[i]->header().snapshot_);
1091 for (uint8_t i = 0; i < batch_size; ++i) {
1092 parents_copy[i] = parents[i];
1100 reinterpret_cast<Page**>(parents),
1102 reinterpret_cast<Page**>(out)));
1105 for (uint8_t i = 0; i < batch_size; ++i) {
1121 #define EXPLICIT_INSTANTIATION_GET(x) template ErrorCode ArrayStorage::get_record_primitive< x > \
1122 (thread::Thread* context, ArrayOffset offset, x *payload, uint16_t payload_offset)
1125 #define EX_GET_BATCH(x) template ErrorCode ArrayStorage::get_record_primitive_batch< x > \
1126 (thread::Thread* context, uint16_t payload_offset, \
1127 uint16_t batch_size, const ArrayOffset* offset_batch, x *payload)
1130 #define EX_GET_BATCH_IMPL(x) template ErrorCode \
1131 ArrayStoragePimpl::get_record_primitive_batch< x > \
1132 (thread::Thread* context, uint16_t payload_offset, \
1133 uint16_t batch_size, const ArrayOffset* offset_batch, x *payload)
1136 #define EXPLICIT_INSTANTIATION_OV(x) template ErrorCode\
1137 ArrayStorage::overwrite_record_primitive< x > \
1138 (thread::Thread* context, ArrayOffset offset, x payload, uint16_t payload_offset)
1141 #define EX_OV_REC(x) template ErrorCode\
1142 ArrayStorage::overwrite_record_primitive< x > \
1143 (thread::Thread* context, ArrayOffset offset, Record* record, x payload, uint16_t payload_offset)
1146 #define EX_OV_REC_IMPL(x) template ErrorCode\
1147 ArrayStoragePimpl::overwrite_record_primitive< x > \
1148 (thread::Thread* context, ArrayOffset offset, Record* record, x payload, uint16_t payload_offset)
1151 #define EXPLICIT_INSTANTIATION_INC(x) template ErrorCode ArrayStorage::increment_record< x > \
1152 (thread::Thread* context, ArrayOffset offset, x* value, uint16_t payload_offset)
1155 #define EXPLICIT_INSTANTIATION_GET_IMPL(x) template ErrorCode \
1156 ArrayStoragePimpl::get_record_primitive< x > \
1157 (thread::Thread* context, ArrayOffset offset, x *payload, uint16_t payload_offset)
1160 #define EXPLICIT_INSTANTIATION_GET_OV_IMPL(x) template ErrorCode \
1161 ArrayStoragePimpl::overwrite_record_primitive< x > \
1162 (thread::Thread* context, ArrayOffset offset, x payload, uint16_t payload_offset)
1165 #define EXPLICIT_INSTANTIATION_GET_INC_IMPL(x) template ErrorCode \
1166 ArrayStoragePimpl::increment_record< x > \
1167 (thread::Thread* context, ArrayOffset offset, x* value, uint16_t payload_offset)
1170 #define EX_INC1S(x) template ErrorCode ArrayStorage::increment_record_oneshot< x > \
1171 (thread::Thread* context, ArrayOffset offset, x value, uint16_t payload_offset)
1174 #define EX_INC1S_IMPL(x) template ErrorCode ArrayStoragePimpl::increment_record_oneshot< x > \
1175 (thread::Thread* context, ArrayOffset offset, x value, uint16_t payload_offset)
uint16_t get_leaf_record_count() const
ErrorStack verify_single_thread(thread::Thread *context)
const memory::GlobalVolatilePageResolver & get_global_volatile_page_resolver() const
Returns the page resolver to convert page ID to page pointer.
uint8_t levels_
Number of levels.
ErrorCode increment_record(thread::Thread *context, ArrayOffset offset, T *value, uint16_t payload_offset)
This one further optimizes overwrite_record_primitive() for the frequent use case of incrementing som...
Metadata meta_
common part of the metadata.
xct::Xct & get_current_xct()
Returns the transaction that is currently running on this thread.
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 get_record_for_write_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch)
T align8(T value)
8-alignment.
0x0826 : "STORAGE: Too large array size specified. The size of an array storage must be smaller than ...
ErrorCode locate_record_for_read(thread::Thread *context, ArrayOffset offset, Record **out, bool *snapshot_record) __attribute__((always_inline))
const ArrayMetadata & get_meta() const
Represents one record in our key-value store.
StorageStatus status_
Status of the storage.
Represents a pointer to another page (usually a child page).
ErrorCode follow_page_pointers_for_write_batch(uint16_t batch_size, storage::VolatilePageInit page_initializer, storage::DualPagePointer **pointers, storage::Page **parents, const uint16_t *index_in_parents, storage::Page **out)
Batched version of follow_page_pointer with will_modify==true and tolerate_null_pointer==true.
SnapshotLocalPageId extract_local_page_id_from_snapshot_pointer(SnapshotPagePointer pointer)
ErrorCode follow_pointers_for_write_batch(thread::Thread *context, uint16_t batch_size, ArrayPage **parents, const uint16_t *index_in_parents, ArrayPage **out)
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Automatically calls if uninitialize() wasn't called when it gets out of scope, and just complains whe...
Declares all log types used in this storage type.
uint8_t route[8]
[0] means record ordinal in leaf, [1] in its parent page, [2]...
Pimpl object of ArrayStorage.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
Compactly represents the route to reach the given offset.
ErrorCode get_record_for_write(thread::Thread *context, ArrayOffset offset, Record **record) __attribute__((always_inline))
ErrorCode get_record(thread::Thread *context, ArrayOffset offset, void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
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)
Represents a key-value store based on a dense and regular array.
Epoch get_initial_current_epoch() const
ErrorCode locate_record_for_write(thread::Thread *context, ArrayOffset offset, Record **out) __attribute__((always_inline))
const ArrayMetadata * get_array_metadata() const
Represents one thread running on one NUMA core.
const ArrayOffset kMaxArrayOffset
The maximum value allowed for ArrayOffset.
ErrorCode on_record_read(bool intended_for_write, RwLockableXctId *tid_address, XctId *observed_xid, ReadXctAccess **read_set_address, bool no_readset_if_moved=false, bool no_readset_if_next_layer=false)
The general logic invoked for every record read.
static uint16_t calculate_log_length(uint16_t payload_count) __attribute__((always_inline))
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.
const GlobalVolatilePageResolver & get_global_volatile_page_resolver() const
Returns the page resolver to convert volatile page ID to page pointer.
void populate_primitive(StorageId storage_id, ArrayOffset offset, T payload, uint16_t payload_offset) __attribute__((always_inline))
For primitive types.
void prefetch_cacheline(const void *address)
Prefetch one cacheline to L1 cache.
Represents a pointer to a volatile page with modification count for preventing ABA.
Represents a user transaction.
uint16_t get_payload_size() const
Returns byte size of one record in this array storage without internal overheads. ...
Persistent status part of Transaction ID.
ErrorCode get_record_primitive(thread::Thread *context, ArrayOffset offset, T *payload, uint16_t payload_offset)
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...
ErrorStack uninitialize() override final
Typical implementation of Initializable::uninitialize() that provides uninitialize-once semantics...
Brings error stacktrace information as return value of functions.
Represents one data page in Array Storage.
XctId xct_id_
the second 64bit: Persistent status part of TID.
void array_volatile_page_init(const VolatilePageInitArguments &args)
volatile page initialize callback for ArrayPage.
Engine * engine_
Most attachable object stores an engine pointer (local engine), so we define it here.
The storage has been created and ready for use.
ErrorCode add_to_write_set(storage::StorageId storage_id, RwLockableXctId *owner_id_address, char *payload_address, log::RecordLogType *log_entry)
Add the given record to the write set of this transaction.
Definitions of IDs in this package and a few related constant values.
Holds a set of read-only file objects for snapshot files.
ErrorCode get_record_payload(thread::Thread *context, ArrayOffset offset, const void **payload) __attribute__((always_inline))
ErrorCode get_root_page(thread::Thread *context, bool for_write, ArrayPage **out) __attribute__((always_inline))
const uint16_t kDataSize
Byte size of data region in each page of array storage.
bool is_valid() const __attribute__((always_inline))
uint16_t get_payload_size() const
McsBlockIndex get_tail_waiter_block() const
ErrorCode overwrite_record(thread::Thread *context, ArrayOffset offset, const void *payload)
Overwrites one record of the given offset in this array storage.
ErrorCode get_record_primitive_batch(thread::Thread *context, uint16_t payload_offset, uint16_t batch_size, const ArrayOffset *offset_batch, T *payload)
batched interface
ArrayOffset get_array_size() const
Returns the size of this array.
savepoint::SavepointManager * get_savepoint_manager() const
See Savepoint Manager.
McsRwLock lock_
the first 64bit: Locking part of TID
ArrayOffset begin_
Inclusive beginning of the offset range.
ErrorStack verify_single_thread(thread::Thread *context)
bool is_deleted() const __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.
ErrorCode increment_record(thread::Thread *context, ArrayOffset offset, T *value, uint16_t payload_offset)
DualPagePointer root_page_pointer_
Points to the root page (or something equivalent).
ErrorCode get_record(thread::Thread *context, ArrayOffset offset, void *payload)
Retrieves one record of the given offset in this array storage.
If you want more than this, you should loop.
log::ThreadLogBuffer & get_thread_log_buffer()
Returns the private log buffer for this thread.
ErrorCode overwrite_record(thread::Thread *context, ArrayOffset offset, const void *payload, uint16_t payload_offset, uint16_t payload_count) __attribute__((always_inline))
VolatilePagePointer volatile_pointer_
ArrayMetadata meta_
metadata of this storage.
ErrorCode lookup_for_read(thread::Thread *context, ArrayOffset offset, ArrayPage **out, uint16_t *index, bool *snapshot_page) __attribute__((always_inline))
Log type of array-storage's overwrite operation.
bool is_moved() const __attribute__((always_inline))
const DualPagePointer & get_interior_record(uint16_t record) const __attribute__((always_inline))
const ArrayRange & get_array_range() const
char payload_[8]
Arbitrary payload given by the user.
ArrayStorageControlBlock * control_block_
The shared data on shared memory that has been initialized in some SOC or master engine.
const Record * get_leaf_record(uint16_t record, uint16_t payload_size) const __attribute__((always_inline))
#define CHECK_AND_ASSERT(x)
bool is_being_written() const __attribute__((always_inline))
Calls Initializable::uninitialize() automatically when it gets out of scope.
Constants and methods related to CPU cacheline and its prefetching.
ErrorStack initialize() override final
Typical implementation of Initializable::initialize() that provides initialize-once semantics...
ArrayStorageControlBlock *const control_block_
ErrorCode follow_page_pointers_for_read_batch(uint16_t batch_size, storage::VolatilePageInit page_initializer, bool tolerate_null_pointer, bool take_ptr_set_snapshot, storage::DualPagePointer **pointers, storage::Page **parents, const uint16_t *index_in_parents, bool *followed_snapshots, storage::Page **out)
Batched version of follow_page_pointer with will_modify==false.
0x0802 : "STORAGE: This storage already exists" .
ErrorCode get_record_for_write_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch) __attribute__((always_inline))
uint16_t get_levels() const
static uint16_t calculate_log_length(ValueType value_type) __attribute__((always_inline))
SnapshotPagePointer snapshot_pointer_
ErrorCode get_record_payload(thread::Thread *context, ArrayOffset offset, const void **payload)
Retrieves a pointer to the entire payload.
LookupRoute find_route(ArrayOffset offset) const __attribute__((always_inline))
void populate(StorageId storage_id, ArrayOffset offset, const void *payload, uint16_t payload_offset, uint16_t payload_count) __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)
Just a marker to denote that the memory region represents a data page.
static std::vector< uint64_t > calculate_required_pages(uint64_t array_size, uint16_t payload)
Calculate leaf/interior pages we need.
Log type of array-storage's increment operation.
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.
ErrorStack hcc_reset_all_temperature_stat()
Resets all volatile pages' temperature stat to be zero in this storage.
static void release_pages_recursive(const memory::GlobalVolatilePageResolver &resolver, memory::PageReleaseBatch *batch, VolatilePagePointer volatile_page_id)
Used only from drop()
bool contains(ArrayOffset offset) const
static std::vector< uint64_t > calculate_offset_intervals(uint8_t levels, uint16_t payload)
The offset interval a single page represents in each level.
void populate(StorageId storage_id, ArrayOffset offset, T payload, uint16_t payload_offset) __attribute__((always_inline))
ArrayOffset get_array_size() const
uint8_t get_levels() const
Returns the number of levels.
ErrorCode get_record_for_write(thread::Thread *context, ArrayOffset offset, Record **record)
Retrieves a pointer to the entire record for write (thus always in volatile page).
ErrorCode increment_record_oneshot(thread::Thread *context, ArrayOffset offset, T value, uint16_t payload_offset)
This is a faster increment that does not return the value after increment.
ErrorCode lookup_for_write_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, Record **record_batch)
ErrorStack load(const StorageControlBlock &snapshot_block)
ErrorCode get_record_payload_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, const void **payload_batch)
Represents an offset range in an array storage.
ErrorStack hcc_reset_all_temperature_stat_intermediate(VolatilePagePointer intermediate_page_id)
#define CHECK_ERROR_CODE(x)
This macro calls x and checks its returned error code.
Packages logic and required properties to calculate LookupRoute in array storage from offset...
ErrorCode get_record_primitive(thread::Thread *context, ArrayOffset offset, T *payload, uint16_t payload_offset)
Retrieves a part of record of the given offset as a primitive type in this array storage.
IsolationLevel get_isolation_level() const
Returns the level of isolation for this transaction.
uint16_t get_records_in_leaf() const __attribute__((always_inline))
ValueType
Used in ArrayIncrementLogType.
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
VolatilePagePointer construct_volatile_page_pointer(uint64_t word)
const ErrorStack kRetOk
Normal return value for no-error case.
uint8_t calculate_levels(const ArrayMetadata &metadata)
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 increment_record_oneshot(thread::Thread *context, ArrayOffset offset, T value, uint16_t payload_offset)
int64_t int_div_ceil(int64_t dividee, int64_t dividor)
Efficient ceil(dividee/dividor) for integer.
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.
#define INSTANTIATE_ALL_NUMERIC_TYPES(M)
INSTANTIATE_ALL_TYPES minus std::string.
Definitions of IDs in this package and a few related constant values.
LookupRouteFinder route_finder_
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))
ErrorStack hcc_reset_all_temperature_stat()
const uint16_t kInteriorFanout
Max number of entries in an interior page of array storage.
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
#define WRAP_ERROR_CODE(x)
Same as CHECK_ERROR(x) except it receives only an error code, thus more efficient.
ErrorCode get_record_payload_batch(thread::Thread *context, uint16_t batch_size, const ArrayOffset *offset_batch, const void **payload_batch) __attribute__((always_inline))
ErrorStack create(const Metadata &metadata)
A base layout of shared data for all storage types.
char * reserve_new_log(uint16_t log_length) __attribute__((always_inline))
Reserves a space for a new (uncommitted) log entry at the tail.
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
ErrorCode
Enum of error codes defined in error_code.xmacro.
xct::RwLockableXctId owner_id_
This indicates the transaction that most recently modified this record.
ErrorCode overwrite_record_primitive(thread::Thread *context, ArrayOffset offset, T payload, uint16_t payload_offset)
bool is_keylocked() const __attribute__((always_inline))
ErrorCode overwrite_record_primitive(thread::Thread *context, ArrayOffset offset, T payload, uint16_t payload_offset)
Overwrites a part of record of the given offset as a primitive type in this array storage...
thread::ThreadId get_tail_waiter() const
uint8_t get_level() const
void initialize_volatile_page(Epoch initial_epoch, StorageId storage_id, VolatilePagePointer page_id, uint16_t payload_size, uint8_t level, const ArrayRange &array_range)