Skip to content

Commit 2d61e65

Browse files
committed
support btree to json
1 parent aec4a99 commit 2d61e65

File tree

7 files changed

+151
-156
lines changed

7 files changed

+151
-156
lines changed

source/LeanStore.hpp

+31-46
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,12 @@ class LeanStore {
4444
~LeanStore();
4545

4646
public:
47-
/**
48-
* @brief Register a BTreeLL
49-
*
50-
* @param name The unique name of the btree
51-
* @param config The config of the btree
52-
* @param btree The pointer to store the registered btree
53-
* @return Whether the btree is successfully registered
54-
*/
47+
/// Register a BTreeLL
48+
///
49+
/// @param name The unique name of the btree
50+
/// @param config The config of the btree
51+
/// @param btree The pointer to store the registered btree
52+
/// @return Whether the btree is successfully registered
5553
[[nodiscard]] bool RegisterBTreeLL(
5654
const std::string& name, storage::btree::BTreeGeneric::Config& config,
5755
storage::btree::BTreeLL** btree) {
@@ -60,40 +58,33 @@ class LeanStore {
6058
return (*btree) != nullptr;
6159
}
6260

63-
/**
64-
* @brief Get a registered BTreeLL
65-
*
66-
* @param name The unique name of the btree
67-
* @param btree The pointer to store the found btree
68-
* @return Whether the btree is found
69-
*/
61+
/// Get a registered BTreeLL
62+
///
63+
/// @param name The unique name of the btree
64+
/// @param btree The pointer to store the found btree
65+
/// @return Whether the btree is found
7066
[[nodiscard]] bool GetBTreeLL(const std::string& name,
7167
storage::btree::BTreeLL** btree) {
7268
*btree = dynamic_cast<storage::btree::BTreeLL*>(
7369
storage::TreeRegistry::sInstance->GetTree(name));
7470
return *btree != nullptr;
7571
}
7672

77-
/**
78-
* @brief Unregister a BTreeLL
79-
*
80-
* TODO(jian.z): reclaim all the buffer frames in memory and pages in disk
81-
* occupied by the tree.
82-
*
83-
* @param name The unique name of the btree
84-
*/
73+
/// Unregister a BTreeLL
74+
/// @param name The unique name of the btree
8575
void UnRegisterBTreeLL(const std::string& name) {
76+
auto btree = dynamic_cast<storage::btree::BTreeGeneric*>(
77+
storage::TreeRegistry::sInstance->GetTree(name));
78+
leanstore::storage::btree::BTreeGeneric::FreeAndReclaim(*btree);
8679
storage::TreeRegistry::sInstance->UnregisterTree(name);
8780
}
8881

89-
/**
90-
* @brief Register a BTreeVI
91-
*
92-
* @param name The unique name of the btree
93-
* @param config The config of the btree
94-
* @param btree The pointer to store the registered btree
95-
* @return Whether the btree is successfully registered
96-
*/
82+
/// Register a BTreeVI
83+
///
84+
/// @param name The unique name of the btree
85+
/// @param config The config of the btree
86+
/// @param btree The pointer to store the registered btree
87+
/// @return Whether the btree is successfully registered
9788
[[nodiscard]] bool RegisterBTreeVI(
9889
const std::string& name, storage::btree::BTreeGeneric::Config& config,
9990
storage::btree::BTreeVI** btree) {
@@ -113,6 +104,8 @@ class LeanStore {
113104

114105
// clean resource on failure
115106
SCOPED_DEFER(if (!success && graveyard != nullptr) {
107+
leanstore::storage::btree::BTreeGeneric::FreeAndReclaim(
108+
*static_cast<leanstore::storage::btree::BTreeGeneric*>(graveyard));
116109
TreeRegistry::sInstance->UnRegisterTree(graveyard->mTreeId);
117110
});
118111

@@ -122,28 +115,20 @@ class LeanStore {
122115
return success;
123116
}
124117

125-
/**
126-
* @brief Get a registered BTreeVI
127-
*
128-
* @param name The unique name of the btree
129-
* @param btree The pointer to store the found btree
130-
* @return Whether the btree is found
131-
*/
118+
/// Get a registered BTreeVI
119+
///
120+
/// @param name The unique name of the btree
121+
/// @param btree The pointer to store the found btree
122+
/// @return Whether the btree is found
132123
[[nodiscard]] bool GetBTreeVI(const std::string& name,
133124
storage::btree::BTreeVI** btree) {
134125
*btree = dynamic_cast<storage::btree::BTreeVI*>(
135126
storage::TreeRegistry::sInstance->GetTree(name));
136127
return *btree != nullptr;
137128
}
138129

139-
/**
140-
* @brief Unregister a BTreeVI
141-
*
142-
* TODO(jian.z): reclaim all the buffer frames in memory and pages in disk
143-
* occupied by the tree.
144-
*
145-
* @param name The unique name of the btree
146-
*/
130+
/// Unregister a BTreeVI
131+
/// @param name The unique name of the btree
147132
void UnRegisterBTreeVI(const std::string& name) {
148133
auto btree = dynamic_cast<storage::btree::BTreeGeneric*>(
149134
storage::TreeRegistry::sInstance->GetTree(name));

source/storage/btree/BTreeVI.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,8 @@ OP_RESULT BTreeVI::insert(Slice key, Slice val) {
378378
if (autoCommit) {
379379
cr::Worker::my().commitTX();
380380
}
381-
auto doc = BTreeGeneric::ToJSON(*this);
381+
rapidjson::Document doc(rapidjson::kObjectType);
382+
BTreeGeneric::ToJSON(*this, &doc);
382383
DLOG(INFO) << "BTreeVI after insert: " << leanstore::utils::JsonToStr(&doc);
383384
});
384385

source/storage/btree/core/BTreeGeneric.cpp

+20-21
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ s16 BTreeGeneric::mergeLeftIntoRight(ExclusivePageGuard<BTreeNode>& parent,
435435
}
436436
return 2;
437437
}
438-
// -------------------------------------------------------------------------------------
438+
439439
// returns true if it has exclusively locked anything
440440

441441
BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
@@ -445,18 +445,18 @@ BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
445445
if (c_guard->fillFactorAfterCompaction() >= 0.9) {
446446
return XMergeReturnCode::NOTHING;
447447
}
448-
// -------------------------------------------------------------------------------------
448+
449449
const u8 MAX_MERGE_PAGES = FLAGS_xmerge_k;
450450
s16 pos = parent_handler.mPosInParent;
451451
u8 pages_count = 1;
452452
s16 max_right;
453453
ARRAY_ON_STACK(guards, HybridPageGuard<BTreeNode>, MAX_MERGE_PAGES);
454454
ARRAY_ON_STACK(fully_merged, bool, MAX_MERGE_PAGES);
455-
// -------------------------------------------------------------------------------------
455+
456456
guards[0] = std::move(c_guard);
457457
fully_merged[0] = false;
458458
double total_fill_factor = guards[0]->fillFactorAfterCompaction();
459-
// -------------------------------------------------------------------------------------
459+
460460
// Handle upper swip instead of avoiding p_guard->mNumSeps -1 swip
461461
if (isMetaNode(p_guard) || !guards[0]->mIsLeaf) {
462462
c_guard = std::move(guards[0]);
@@ -469,7 +469,7 @@ BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
469469
c_guard = std::move(guards[0]);
470470
return XMergeReturnCode::NOTHING;
471471
}
472-
// -------------------------------------------------------------------------------------
472+
473473
guards[max_right - pos] =
474474
HybridPageGuard<BTreeNode>(p_guard, p_guard->getChild(max_right));
475475
fully_merged[max_right - pos] = false;
@@ -485,10 +485,10 @@ BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
485485
c_guard = std::move(guards[0]);
486486
return XMergeReturnCode::NOTHING;
487487
}
488-
// -------------------------------------------------------------------------------------
488+
489489
ExclusivePageGuard<BTreeNode> p_x_guard = std::move(p_guard);
490490
p_x_guard.incrementGSN();
491-
// -------------------------------------------------------------------------------------
491+
492492
XMergeReturnCode ret_code = XMergeReturnCode::PARTIAL_MERGE;
493493
s16 left_hand, right_hand, ret;
494494
while (true) {
@@ -501,9 +501,9 @@ BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
501501
}
502502
if (right_hand == pos)
503503
break;
504-
// -------------------------------------------------------------------------------------
504+
505505
left_hand = right_hand - 1;
506-
// -------------------------------------------------------------------------------------
506+
507507
{
508508
ExclusivePageGuard<BTreeNode> right_x_guard(
509509
std::move(guards[right_hand - pos]));
@@ -528,7 +528,6 @@ BTreeGeneric::XMergeReturnCode BTreeGeneric::XMerge(
528528
ENSURE(false);
529529
}
530530
}
531-
// -------------------------------------------------------------------------------------
532531
}
533532
if (c_guard.guard.state == GUARD_STATE::MOVED)
534533
c_guard = std::move(guards[0]);
@@ -552,15 +551,15 @@ s64 BTreeGeneric::iterateAllPagesRec(HybridPageGuard<BTreeNode>& node_guard,
552551
c_guard.JumpIfModifiedByOthers();
553552
res += iterateAllPagesRec(c_guard, inner, leaf);
554553
}
555-
// -------------------------------------------------------------------------------------
554+
556555
Swip<BTreeNode>& c_swip = node_guard->mRightMostChildSwip;
557556
auto c_guard = HybridPageGuard(node_guard, c_swip);
558557
c_guard.JumpIfModifiedByOthers();
559558
res += iterateAllPagesRec(c_guard, inner, leaf);
560-
// -------------------------------------------------------------------------------------
559+
561560
return res;
562561
}
563-
// -------------------------------------------------------------------------------------
562+
564563
s64 BTreeGeneric::iterateAllPages(BTreeNodeCallback inner,
565564
BTreeNodeCallback leaf) {
566565
while (true) {
@@ -574,36 +573,36 @@ s64 BTreeGeneric::iterateAllPages(BTreeNodeCallback inner,
574573
}
575574
}
576575
}
577-
// -------------------------------------------------------------------------------------
576+
578577
u64 BTreeGeneric::getHeight() {
579578
return mHeight.load();
580579
}
581-
// -------------------------------------------------------------------------------------
580+
582581
u64 BTreeGeneric::countEntries() {
583582
return iterateAllPages([](BTreeNode&) { return 0; },
584583
[](BTreeNode& node) { return node.mNumSeps; });
585584
}
586-
// -------------------------------------------------------------------------------------
585+
587586
u64 BTreeGeneric::countPages() {
588587
return iterateAllPages([](BTreeNode&) { return 1; },
589588
[](BTreeNode&) { return 1; });
590589
}
591-
// -------------------------------------------------------------------------------------
590+
592591
u64 BTreeGeneric::countInner() {
593592
return iterateAllPages([](BTreeNode&) { return 1; },
594593
[](BTreeNode&) { return 0; });
595594
}
596-
// -------------------------------------------------------------------------------------
595+
597596
double BTreeGeneric::averageSpaceUsage() {
598597
ENSURE(false); // TODO
599598
}
600-
// -------------------------------------------------------------------------------------
599+
601600
u32 BTreeGeneric::bytesFree() {
602601
return iterateAllPages(
603602
[](BTreeNode& inner) { return inner.freeSpaceAfterCompaction(); },
604603
[](BTreeNode& leaf) { return leaf.freeSpaceAfterCompaction(); });
605604
}
606-
// -------------------------------------------------------------------------------------
605+
607606
void BTreeGeneric::printInfos(uint64_t totalSize) {
608607
HybridPageGuard<BTreeNode> p_guard(mMetaNodeSwip);
609608
HybridPageGuard r_guard(p_guard, p_guard->mRightMostChildSwip);
@@ -613,5 +612,5 @@ void BTreeGeneric::printInfos(uint64_t totalSize) {
613612
<< " height:" << mHeight << " rootCnt:" << r_guard->mNumSeps
614613
<< " bytesFree:" << bytesFree() << endl;
615614
}
616-
// -------------------------------------------------------------------------------------
615+
617616
} // namespace leanstore::storage::btree

source/storage/btree/core/BTreeGeneric.hpp

+60-25
Original file line numberDiff line numberDiff line change
@@ -259,39 +259,30 @@ class BTreeGeneric : public leanstore::storage::BufferManagedTree {
259259
exclusiveGuardedMetaNode.reclaim();
260260
}
261261

262-
static rapidjson::Document ToJSON(BTreeGeneric& btree) {
262+
static void ToJSON(BTreeGeneric& btree, rapidjson::Document* resultDoc) {
263+
DCHECK(resultDoc->IsObject());
264+
auto& allocator = resultDoc->GetAllocator();
265+
266+
// meta node
263267
HybridPageGuard<BTreeNode> guardedMetaNode(btree.mMetaNodeSwip);
268+
rapidjson::Value metaJson(rapidjson::kObjectType);
269+
guardedMetaNode.mBf->ToJSON(&metaJson, allocator);
270+
resultDoc->AddMember("metaNode", metaJson, allocator);
271+
272+
// root node
264273
HybridPageGuard<BTreeNode> guardedRootNode(
265274
guardedMetaNode, guardedMetaNode->mRightMostChildSwip);
266-
return ToJSONRecursive(guardedRootNode);
275+
rapidjson::Value rootJson(rapidjson::kObjectType);
276+
ToJSONRecursive(guardedRootNode, &rootJson, allocator);
277+
resultDoc->AddMember("rootNode", rootJson, allocator);
267278
}
268279

269280
private:
270281
static void freeBTreeNodesRecursive(HybridPageGuard<BTreeNode>& guardedNode);
271282

272-
static rapidjson::Document ToJSONRecursive(
273-
HybridPageGuard<BTreeNode>& guardedNode) {
274-
auto bfDoc = guardedNode.mBf->ToJSON();
275-
// auto& allocator = bfDoc.GetAllocator();
276-
277-
// auto nodeDoc = guardedNode->ToJSON();
278-
// bfDoc.AddMember("BTreeNode", nodeDoc, allocator);
279-
280-
// if (guardedNode->mIsLeaf) {
281-
// return bfDoc;
282-
// }
283-
// for (auto i = 0u; i <= guardedNode->mNumSeps; ++i) {
284-
// auto childSwip = guardedNode->GetChildIncludingRightMost(i);
285-
// HybridPageGuard<BTreeNode> guardedChild(guardedNode, childSwip);
286-
// auto childDoc = ToJSONRecursive(guardedChild);
287-
// auto childName = "mChild_" + std::to_string(i);
288-
// guardedChild.unlock();
289-
// leanstore::utils::JsonValue memberName(childName.c_str(), allocator);
290-
// bfDoc.AddMember(memberName, childDoc, allocator);
291-
// }
292-
293-
return bfDoc;
294-
}
283+
static void ToJSONRecursive(HybridPageGuard<BTreeNode>& guardedNode,
284+
rapidjson::Value* resultObj,
285+
rapidjson::Value::AllocatorType& allocator);
295286

296287
public:
297288
static constexpr std::string TREE_ID = "treeId";
@@ -313,6 +304,50 @@ inline void BTreeGeneric::freeBTreeNodesRecursive(
313304
exclusiveGuardedNode.reclaim();
314305
}
315306

307+
inline void BTreeGeneric::ToJSONRecursive(
308+
HybridPageGuard<BTreeNode>& guardedNode, rapidjson::Value* resultObj,
309+
rapidjson::Value::AllocatorType& allocator) {
310+
311+
DCHECK(resultObj->IsObject());
312+
guardedNode.mBf->ToJSON(resultObj, allocator);
313+
314+
// btree node
315+
{
316+
rapidjson::Value nodeObj(rapidjson::kObjectType);
317+
guardedNode->ToJSON(&nodeObj, allocator);
318+
resultObj->AddMember("btreeNode", nodeObj, allocator);
319+
}
320+
321+
if (guardedNode->mIsLeaf) {
322+
return;
323+
}
324+
325+
rapidjson::Value childrenJson(rapidjson::kArrayType);
326+
for (auto i = 0u; i < guardedNode->mNumSeps; ++i) {
327+
auto childSwip = guardedNode->getChild(i);
328+
HybridPageGuard<BTreeNode> guardedChild(guardedNode, childSwip);
329+
330+
rapidjson::Value childObj(rapidjson::kObjectType);
331+
ToJSONRecursive(guardedChild, &childObj, allocator);
332+
guardedChild.unlock();
333+
334+
childrenJson.PushBack(childObj, allocator);
335+
}
336+
337+
if (guardedNode->mRightMostChildSwip != nullptr) {
338+
HybridPageGuard<BTreeNode> guardedChild(guardedNode,
339+
guardedNode->mRightMostChildSwip);
340+
rapidjson::Value childObj(rapidjson::kObjectType);
341+
ToJSONRecursive(guardedChild, &childObj, allocator);
342+
guardedChild.unlock();
343+
344+
childrenJson.PushBack(childObj, allocator);
345+
}
346+
347+
// children
348+
resultObj->AddMember("mChildren", childrenJson, allocator);
349+
}
350+
316351
inline void BTreeGeneric::IterateChildSwips(
317352
BufferFrame& bf, std::function<bool(Swip<BufferFrame>&)> callback) {
318353
// Pre: bf is read locked

0 commit comments

Comments
 (0)