libfoedus-core
FOEDUS Core Library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
array_page_impl.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
19 
20 #include <cstring>
21 
22 #include "foedus/engine.hpp"
23 #include "foedus/epoch.hpp"
27 #include "foedus/thread/thread.hpp"
28 
29 namespace foedus {
30 namespace storage {
31 namespace array {
33  Epoch initial_epoch,
34  StorageId storage_id,
35  SnapshotPagePointer page_id,
36  uint16_t payload_size,
37  uint8_t level,
38  const ArrayRange& array_range) {
39  ASSERT_ND(initial_epoch.is_valid());
40  std::memset(this, 0, kPageSize);
41  header_.init_snapshot(page_id, storage_id, kArrayPageType);
42  payload_size_ = payload_size;
43  level_ = level;
44  array_range_ = array_range;
45  if (is_leaf()) {
46  uint16_t records = get_leaf_record_count();
47  for (uint16_t i = 0; i < records; ++i) {
48  auto* rec = get_leaf_record(i, payload_size);
49  rec->owner_id_.lock_.reset();
50  rec->owner_id_.xct_id_.set_epoch(initial_epoch);
51  }
52  }
53 }
54 
56  Epoch initial_epoch,
57  StorageId storage_id,
58  VolatilePagePointer page_id,
59  uint16_t payload_size,
60  uint8_t level,
61  const ArrayRange& array_range) {
62  ASSERT_ND(initial_epoch.is_valid());
63  std::memset(this, 0, kPageSize);
64  header_.init_volatile(page_id, storage_id, kArrayPageType);
65  payload_size_ = payload_size;
66  level_ = level;
67  array_range_ = array_range;
68  if (is_leaf()) {
69  uint16_t records = get_leaf_record_count();
70  for (uint16_t i = 0; i < records; ++i) {
71  auto* rec = get_leaf_record(i, payload_size);
72  rec->owner_id_.lock_.reset();
73  rec->owner_id_.xct_id_.set_epoch(initial_epoch);
74  }
75  }
76 }
77 
79  ASSERT_ND(args.parent_);
80  ASSERT_ND(args.page_);
82  const ArrayPage* parent = reinterpret_cast<const ArrayPage*>(args.parent_);
83  ArrayPage* page = reinterpret_cast<ArrayPage*>(args.page_);
84 
85  Engine* engine = args.context_->get_engine();
86  StorageId storage_id = parent->get_storage_id();
87  ArrayStorage storage(engine, storage_id);
88  ASSERT_ND(storage.exists());
89  const ArrayStorageControlBlock* cb = storage.get_control_block();
90 
91  ArrayRange parent_range = parent->get_array_range();
92  uint8_t parent_level = parent->get_level();
93  ASSERT_ND(parent_level > 0);
94  ASSERT_ND(parent_range.end_ - parent_range.begin_ == cb->intervals_[parent_level]
95  || parent_range.end_ == storage.get_array_size());
96 
97  uint8_t child_level = parent_level - 1U;
98  uint64_t interval = cb->intervals_[child_level];
99  ASSERT_ND(interval > 0);
100  ArrayRange child_range;
101  child_range.begin_ = parent_range.begin_ + args.index_in_parent_ * interval;
102  child_range.end_ = child_range.begin_ + interval;
103  if (child_range.end_ > storage.get_array_size()) {
104  child_range.end_ = storage.get_array_size();
105  }
106  ASSERT_ND(child_range.end_ > 0);
107 
108  // Because this is a new page, records in it are in the earliest epoch of the system
109  Epoch initial_epoch = engine->get_savepoint_manager()->get_initial_current_epoch();
111  initial_epoch,
112  storage_id,
113  args.page_id,
114  storage.get_payload_size(),
115  child_level,
116  child_range);
117 }
118 
119 } // namespace array
120 } // namespace storage
121 } // namespace foedus
uint32_t StorageId
Unique ID for storage.
Definition: storage_id.hpp:55
void init_volatile(VolatilePagePointer page_id, StorageId storage_id, PageType page_type) __attribute__((always_inline))
Definition: page.hpp:284
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
Represents a key-value store based on a dense and regular array.
void initialize_snapshot_page(Epoch initial_epoch, StorageId storage_id, SnapshotPagePointer page_id, uint16_t payload_size, uint8_t level, const ArrayRange &array_range)
Called only when this page is initialized.
Represents a pointer to a volatile page with modification count for preventing ABA.
Definition: storage_id.hpp:194
uint16_t get_payload_size() const
Returns byte size of one record in this array storage without internal overheads. ...
Represents one data page in Array Storage.
Represents a time epoch.
Definition: epoch.hpp:61
void array_volatile_page_init(const VolatilePageInitArguments &args)
volatile page initialize callback for ArrayPage.
Engine * get_engine() const
Definition: thread.cpp:52
ArrayOffset get_array_size() const
Returns the size of this array.
savepoint::SavepointManager * get_savepoint_manager() const
See Savepoint Manager.
Definition: engine.cpp:53
uint16_t index_in_parent_
[IN] Some index (meaning depends on page type) of pointer in parent page to the new page...
Definition: page.hpp:375
ArrayOffset begin_
Inclusive beginning of the offset range.
Definition: array_id.hpp:86
Page * page_
[IN, OUT] The new page to initialize.
Definition: page.hpp:371
thread::Thread * context_
[IN] Thread on which the procedure is running
Definition: page.hpp:367
const ArrayRange & get_array_range() const
ArrayOffset end_
Exclusive end of the offset range.
Definition: array_id.hpp:88
const Record * get_leaf_record(uint16_t record, uint16_t payload_size) const __attribute__((always_inline))
bool exists() const
Returns whether this storage is already created.
Definition: storage.hpp:169
uint64_t SnapshotPagePointer
Page ID of a snapshot page.
Definition: storage_id.hpp:79
Database engine object that holds all resources and provides APIs.
Definition: engine.hpp:109
const Page * parent_
[IN] Parent of the new page.
Definition: page.hpp:373
Set of arguments, both inputs and outputs, given to each volatile page initializer.
Definition: page.hpp:365
bool is_valid() const
Definition: epoch.hpp:96
Represents an offset range in an array storage.
Definition: array_id.hpp:62
VolatilePagePointer page_id
[IN] New page ID
Definition: page.hpp:369
void init_snapshot(SnapshotPagePointer page_id, StorageId storage_id, PageType page_type) __attribute__((always_inline))
Definition: page.hpp:301
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
CONTROL_BLOCK * get_control_block() const
Definition: attachable.hpp:97
const uint16_t kPageSize
A constant defining the page size (in bytes) of both snapshot pages and volatile pages.
Definition: storage_id.hpp:45
void initialize_volatile_page(Epoch initial_epoch, StorageId storage_id, VolatilePagePointer page_id, uint16_t payload_size, uint8_t level, const ArrayRange &array_range)