libfoedus-core
FOEDUS Core Library
array_page_impl.hpp
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  */
18 #ifndef FOEDUS_STORAGE_ARRAY_ARRAY_PAGE_HPP_
19 #define FOEDUS_STORAGE_ARRAY_ARRAY_PAGE_HPP_
20 #include <stdint.h>
21 
22 #include "foedus/assert_nd.hpp"
23 #include "foedus/compiler.hpp"
24 #include "foedus/fwd.hpp"
25 #include "foedus/storage/page.hpp"
31 #include "foedus/xct/xct_id.hpp"
32 
33 namespace foedus {
34 namespace storage {
35 namespace array {
36 
46 class ArrayPage final {
47  public:
51  union Data {
53  // InteriorRecord interior_data[kInteriorFanout];
55  };
56 
57  // A page object is never explicitly instantiated. You must reinterpret_cast.
58  ArrayPage() = delete;
59  ArrayPage(const ArrayPage& other) = delete;
60  ArrayPage& operator=(const ArrayPage& other) = delete;
61 
62  // simple accessors
63  PageHeader& header() { return header_; }
64  const PageHeader& header() const { return header_; }
65  StorageId get_storage_id() const { return header_.storage_id_; }
66  uint16_t get_leaf_record_count() const {
67  return kDataSize / (kRecordOverhead + assorted::align8(payload_size_));
68  }
69  uint16_t get_payload_size() const { return payload_size_; }
70  bool is_leaf() const { return level_ == 0; }
71  uint8_t get_level() const { return level_; }
72  const ArrayRange& get_array_range() const { return array_range_; }
73 
76  Epoch initial_epoch,
77  StorageId storage_id,
78  SnapshotPagePointer page_id,
79  uint16_t payload_size,
80  uint8_t level,
81  const ArrayRange& array_range);
83  Epoch initial_epoch,
84  StorageId storage_id,
85  VolatilePagePointer page_id,
86  uint16_t payload_size,
87  uint8_t level,
88  const ArrayRange& array_range);
89 
90  // Record accesses
91  const Record* get_leaf_record(uint16_t record, uint16_t payload_size) const ALWAYS_INLINE {
92  ASSERT_ND(payload_size_ == payload_size);
93  ASSERT_ND(is_leaf());
94  ASSERT_ND((record + 1) * (kRecordOverhead + assorted::align8(payload_size_)) <= kDataSize);
95  return reinterpret_cast<const Record*>(
96  data_.leaf_data + record * (kRecordOverhead + assorted::align8(payload_size_)));
97  }
98  Record* get_leaf_record(uint16_t record, uint16_t payload_size) ALWAYS_INLINE {
99  ASSERT_ND(payload_size_ == payload_size);
100  ASSERT_ND(is_leaf());
101  ASSERT_ND((record + 1) * (kRecordOverhead + assorted::align8(payload_size_)) <= kDataSize);
102  return reinterpret_cast<Record*>(
103  data_.leaf_data + record * (kRecordOverhead + assorted::align8(payload_size_)));
104  }
105  const DualPagePointer& get_interior_record(uint16_t record) const ALWAYS_INLINE {
106  return const_cast<ArrayPage*>(this)->get_interior_record(record);
107  }
109  ASSERT_ND(!is_leaf());
110  ASSERT_ND(record < kInteriorFanout);
111  return data_.interior_data[record];
112  }
113 
114  uint8_t unused_dummy_func_reserved1() const { return reserved1_; }
115  uint32_t unused_dummy_func_reserved2() const { return reserved2_; }
116 
117  private:
119  PageHeader header_; // +40 -> 40
120 
122  uint16_t payload_size_; // +2 -> 42
123 
125  uint8_t level_; // +1 -> 43
126 
127  uint8_t reserved1_; // +1 -> 44
128  uint32_t reserved2_; // +4 -> 48
129 
135  ArrayRange array_range_; // +16 -> 64
136 
137  // All variables up to here are immutable after the array storage is created.
138 
140  Data data_;
141 };
142 
149 
150 
151 static_assert(sizeof(ArrayPage) == kPageSize, "sizeof(ArrayPage) is not kPageSize");
152 static_assert(sizeof(ArrayPage) - sizeof(ArrayPage::Data) == kHeaderSize, "kHeaderSize is wrong");
153 
154 } // namespace array
155 } // namespace storage
156 } // namespace foedus
157 #endif // FOEDUS_STORAGE_ARRAY_ARRAY_PAGE_HPP_
DualPagePointer interior_data[kInteriorFanout]
T align8(T value)
8-alignment.
Represents one record in our key-value store.
Definition: record.hpp:33
Represents a pointer to another page (usually a child page).
Definition: storage_id.hpp:271
Definitions of IDs in this package and a few related constant values.
const uint16_t kRecordOverhead
Byte size of system-managed region per each record.
Definition: record.hpp:56
uint32_t StorageId
Unique ID for storage.
Definition: storage_id.hpp:55
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
Record * get_leaf_record(uint16_t record, uint16_t payload_size) __attribute__((always_inline))
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.
StorageId storage_id_
ID of the storage this page belongs to.
Definition: page.hpp:196
Represents a pointer to a volatile page with modification count for preventing ABA.
Definition: storage_id.hpp:194
Forward declarations of classes in root package.
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.
Data union for either leaf (dynamic size) or interior (fixed size).
const uint16_t kDataSize
Byte size of data region in each page of array storage.
Definition: array_id.hpp:100
const DualPagePointer & get_interior_record(uint16_t record) const __attribute__((always_inline))
const ArrayRange & get_array_range() const
const Record * get_leaf_record(uint16_t record, uint16_t payload_size) const __attribute__((always_inline))
Definitions of IDs in this package and a few related constant values.
uint64_t SnapshotPagePointer
Page ID of a snapshot page.
Definition: storage_id.hpp:79
Just a marker to denote that a memory region represents a data page.
Definition: page.hpp:184
Set of arguments, both inputs and outputs, given to each volatile page initializer.
Definition: page.hpp:365
uint32_t unused_dummy_func_reserved2() const
Represents an offset range in an array storage.
Definition: array_id.hpp:62
char leaf_data[kInteriorFanout *sizeof(DualPagePointer)]
const uint16_t kHeaderSize
Byte size of header in each page of array storage.
Definition: array_id.hpp:95
const PageHeader & header() const
ArrayPage & operator=(const ArrayPage &other)=delete
DualPagePointer & get_interior_record(uint16_t record) __attribute__((always_inline))
Definitions of IDs in this package and a few related constant values.
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
#define ALWAYS_INLINE
A function suffix to hint that the function should always be inlined.
Definition: compiler.hpp:106
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)