libfoedus-core
FOEDUS Core Library
masstree_storage_debug.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 <glog/logging.h>
21 
22 #include "foedus/engine.hpp"
30 #include "foedus/thread/thread.hpp"
31 
32 namespace foedus {
33 namespace storage {
34 namespace masstree {
35 
37  Engine* engine,
38  bool volatile_only,
39  uint32_t max_pages) {
40  LOG(INFO) << "**"
41  << std::endl << "***************************************************************"
42  << std::endl << "*** Dumping " << MasstreeStorage(engine_, control_block_) << " in details. "
43  << std::endl << "*** volatile_only=" << volatile_only << ", max_pages=" << max_pages
44  << std::endl << "***************************************************************";
45 
46  cache::SnapshotFileSet files(engine);
47  CHECK_ERROR(files.initialize());
49 
50  LOG(INFO) << "First, dumping volatile pages...";
51  DualPagePointer pointer = control_block_->root_page_pointer_;
52  if (pointer.volatile_pointer_.is_null()) {
53  LOG(INFO) << "No volatile pages.";
54  } else {
55  uint32_t remaining = max_pages;
56  CHECK_ERROR(debugout_single_thread_follow(engine, &files, pointer, true, &remaining));
57  }
58  LOG(INFO) << "Dumped volatile pages.";
59  if (!volatile_only) {
60  LOG(INFO) << "Now dumping snapshot pages...";
61  if (pointer.snapshot_pointer_ == 0) {
62  LOG(INFO) << "No snapshot pages.";
63  } else {
64  uint32_t remaining = max_pages;
65  CHECK_ERROR(debugout_single_thread_follow(engine, &files, pointer, false, &remaining));
66  }
67  LOG(INFO) << "Dumped snapshot pages.";
68  }
69 
70  CHECK_ERROR(files.uninitialize());
71  return kRetOk;
72 }
73 
74 
76  Engine* engine,
78  MasstreePage* parent,
79  bool follow_volatile,
80  uint32_t* remaining_pages) {
81  if (((*remaining_pages) == 0) || --(*remaining_pages) == 0) {
82  LOG(INFO) << "Reached write-out max. skip the following";
83  return kRetOk;
84  }
85  // Implementation note:
86  // So far we don't follow foster-twins in debugout_xxx, so this is irrelevant.
87  // However, if we change it later to follow foster-twins,
88  // do not forget about empty-range intermediate pages that only appear as foster twins.
89  // Empty-range border pages are fine. We just see zero records.
90  // Foster-twins are sooner or later adopted, and Master-Tree invariant for intermediate page
91  // guarantees that we can just read the old page. no need to follow foster-twins.
92 
93  LOG(INFO) << *parent;
94  uint16_t key_count = parent->get_key_count();
95  if (parent->is_border()) {
96  MasstreeBorderPage* casted = reinterpret_cast<MasstreeBorderPage*>(parent);
97  for (uint16_t i = 0; i < key_count; ++i) {
98  if (casted->does_point_to_layer(i)) {
100  engine,
101  files,
102  *casted->get_next_layer(i),
103  follow_volatile,
104  remaining_pages));
105  }
106  }
107  } else {
108  MasstreeIntermediatePage* casted = reinterpret_cast<MasstreeIntermediatePage*>(parent);
109  for (MasstreeIntermediatePointerIterator it(casted); it.is_valid(); it.next()) {
111  engine,
112  files,
113  it.get_pointer(),
114  follow_volatile,
115  remaining_pages));
116  }
117  }
118 
119  return kRetOk;
120 }
121 
123  Engine* engine,
124  cache::SnapshotFileSet* files,
125  const DualPagePointer& pointer,
126  bool follow_volatile,
127  uint32_t* remaining_pages) {
128  if ((*remaining_pages) == 0) {
129  return kRetOk;
130  }
131  if (follow_volatile) {
132  if (!pointer.volatile_pointer_.is_null()) {
133  MasstreePage* page = reinterpret_cast<MasstreePage*>(
135  pointer.volatile_pointer_));
136  CHECK_ERROR(debugout_single_thread_recurse(engine, files, page, true, remaining_pages));
137  }
138  } else {
139  if (pointer.snapshot_pointer_ != 0) {
141  buf.alloc(1 << 12U, 1 << 12U, memory::AlignedMemory::kNumaAllocOnnode, 0);
142  MasstreePage* page = reinterpret_cast<MasstreePage*>(buf.get_block());
143  WRAP_ERROR_CODE(files->read_page(pointer.snapshot_pointer_, page));
144  CHECK_ERROR(debugout_single_thread_recurse(engine, files, page, false, remaining_pages));
145  }
146  }
147  return kRetOk;
148 }
149 
150 
152  LOG(INFO) << "**"
153  << std::endl << "***************************************************************"
154  << std::endl << "*** Reseting " << MasstreeStorage(engine_, control_block_) << "'s "
155  << std::endl << "*** temperature stat for HCC"
156  << std::endl << "***************************************************************";
157 
158  DualPagePointer pointer = control_block_->root_page_pointer_;
159  if (pointer.volatile_pointer_.is_null()) {
160  LOG(INFO) << "No volatile pages.";
161  } else {
163  }
164 
165  LOG(INFO) << "Done resettting";
166  return kRetOk;
167 }
168 
169 
171  uint16_t key_count = parent->get_key_count();
172  if (parent->is_border()) {
173  MasstreeBorderPage* casted = reinterpret_cast<MasstreeBorderPage*>(parent);
174  casted->header().hotness_.reset();
175  for (uint16_t i = 0; i < key_count; ++i) {
176  if (casted->does_point_to_layer(i)) {
178  casted->get_next_layer(i)->volatile_pointer_));
179  }
180  }
181  } else {
182  MasstreeIntermediatePage* casted = reinterpret_cast<MasstreeIntermediatePage*>(parent);
183  for (MasstreeIntermediatePointerIterator it(casted); it.is_valid(); it.next()) {
185  it.get_pointer().volatile_pointer_));
186  }
187  }
188 
189  return kRetOk;
190 }
191 
193  VolatilePagePointer page_id) {
194  if (page_id.is_null()) {
195  MasstreePage* page = reinterpret_cast<MasstreePage*>(
198  }
199  return kRetOk;
200 }
201 
202 } // namespace masstree
203 } // namespace storage
204 } // namespace foedus
storage::Page * resolve_offset(uint8_t numa_node, PagePoolOffset offset) const __attribute__((always_inline))
Resolves offset plus NUMA node ID to storage::Page*.
SlotIndex get_key_count() const __attribute__((always_inline))
physical key count (those keys might be deleted) in this page.
numa_alloc_onnode() and numa_free().
Represents a pointer to another page (usually a child page).
Definition: storage_id.hpp:271
ErrorCode read_page(storage::SnapshotPagePointer page_id, void *out)
Automatically calls if uninitialize() wasn't called when it gets out of scope, and just complains whe...
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
bool is_border() const __attribute__((always_inline))
const GlobalVolatilePageResolver & get_global_volatile_page_resolver() const
Returns the page resolver to convert volatile page ID to page pointer.
Represents a pointer to a volatile page with modification count for preventing ABA.
Definition: storage_id.hpp:194
ErrorStack uninitialize() override final
Typical implementation of Initializable::uninitialize() that provides uninitialize-once semantics...
Represents one border page in Masstree Storage.
Brings error stacktrace information as return value of functions.
Definition: error_stack.hpp:81
DualPagePointer * get_next_layer(SlotIndex index) __attribute__((always_inline))
void alloc(uint64_t size, uint64_t alignment, AllocType alloc_type, int numa_node) noexcept
Allocate a memory, releasing the current memory if exists.
Engine * engine_
Most attachable object stores an engine pointer (local engine), so we define it here.
Definition: attachable.hpp:107
Holds a set of read-only file objects for snapshot files.
ErrorStack hcc_reset_all_temperature_stat_follow(VolatilePagePointer page_id)
Definitions of IDs in this package and a few related constant values.
Common base of MasstreeIntermediatePage and MasstreeBorderPage.
VolatilePagePointer volatile_pointer_
Definition: storage_id.hpp:308
MasstreeStorageControlBlock * control_block_
The shared data on shared memory that has been initialized in some SOC or master engine.
Definition: attachable.hpp:111
ErrorStack hcc_reset_all_temperature_stat_recurse(MasstreePage *parent)
Calls Initializable::uninitialize() automatically when it gets out of scope.
ErrorStack initialize() override final
Typical implementation of Initializable::initialize() that provides initialize-once semantics...
Database engine object that holds all resources and provides APIs.
Definition: engine.hpp:109
SnapshotPagePointer snapshot_pointer_
Definition: storage_id.hpp:307
ErrorStack debugout_single_thread_recurse(Engine *engine, cache::SnapshotFileSet *fileset, MasstreePage *parent, bool follow_volatile, uint32_t *remaining_pages)
void * get_block() const
Returns the memory block.
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
Represents one memory block aligned to actual OS/hardware pages.
const ErrorStack kRetOk
Normal return value for no-error case.
ErrorStack hcc_reset_all_temperature_stat()
For stupid reasons (I'm lazy!) these are defined in _debug.cpp.
Represents one intermediate page in Masstree Storage.
ErrorStack debugout_single_thread_follow(Engine *engine, cache::SnapshotFileSet *fileset, const DualPagePointer &pointer, bool follow_volatile, uint32_t *remaining_pages)
assorted::ProbCounter hotness_
Loosely maintained statistics on data temperature.
Definition: page.hpp:268
#define WRAP_ERROR_CODE(x)
Same as CHECK_ERROR(x) except it receives only an error code, thus more efficient.
bool does_point_to_layer(SlotIndex index) const __attribute__((always_inline))
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50
ErrorStack debugout_single_thread(Engine *engine, bool volatile_only, uint32_t max_pages)
These are defined in masstree_storage_debug.cpp.