blob: f411f1f5665fcf85d81bb58a5e0b3729f32c9de9 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
**/
#include "storage/tests/CSBTreePrettyPrinter.hpp"
#include <cstdint>
#include <iostream>
#include <vector>
#include "catalog/CatalogAttribute.hpp"
#include "catalog/CatalogRelation.hpp"
#include "storage/CSBTreeIndexSubBlock.hpp"
#include "types/Type.hpp"
#include "types/TypedValue.hpp"
using std::uint16_t;
namespace quickstep {
std::ostream& operator<<(std::ostream &out, const CSBTreePrettyPrinter &printer) {
printer.putToStream(&out);
return out;
}
void CSBTreePrettyPrinter::putToStream(std::ostream *stream) const {
printNode(csbtree_index_.getRootNodeGroupNumber(), 0, 0, stream);
}
void CSBTreePrettyPrinter::printNode(const int node_group_number,
const uint16_t node_number,
const int node_depth,
std::ostream *stream) const {
advanceLine(node_depth, stream);
const char *node_ptr = static_cast<const char*>(csbtree_index_.getNode(node_group_number, node_number));
const CSBTreeIndexSubBlock::NodeHeader *node_header
= reinterpret_cast<const CSBTreeIndexSubBlock::NodeHeader*>(node_ptr);
*stream << "Node ";
if (node_header->is_leaf) {
*stream << "(leaf, ";
*stream << "num_keys: " << node_header->num_keys;
*stream << ", right_sibling: ";
if (node_header->node_group_reference == CSBTreeIndexSubBlock::kNodeGroupNextLeaf) {
*stream << "next in group";
} else if (node_header->node_group_reference == CSBTreeIndexSubBlock::kNodeGroupNone) {
*stream << "none";
} else {
*stream << node_header->node_group_reference;
}
*stream << ")\n";
for (uint16_t key_num = 0;
key_num < node_header->num_keys;
++key_num) {
advanceLine(node_depth, stream);
printKey(node_ptr
+ sizeof(CSBTreeIndexSubBlock::NodeHeader)
+ key_num * csbtree_index_.key_tuple_id_pair_length_bytes_,
stream);
*stream << " -> ";
*stream << *reinterpret_cast<const tuple_id*>(node_ptr
+ sizeof(CSBTreeIndexSubBlock::NodeHeader)
+ key_num * csbtree_index_.key_tuple_id_pair_length_bytes_
+ csbtree_index_.key_length_bytes_);
*stream << "\n";
}
} else {
*stream << "(internal, ";
*stream << "num_keys: " << node_header->num_keys;
*stream << ", child: " << node_header->node_group_reference;
*stream << ")\n";
printNode(node_header->node_group_reference,
0,
node_depth + 1,
stream);
for (uint16_t key_num = 0;
key_num < node_header->num_keys;
++key_num) {
advanceLine(node_depth, stream);
*stream << "<";
printKey(node_ptr
+ sizeof(CSBTreeIndexSubBlock::NodeHeader)
+ key_num * csbtree_index_.key_length_bytes_,
stream);
*stream << ">\n";
printNode(node_header->node_group_reference,
key_num + 1,
node_depth + 1,
stream);
}
}
}
void CSBTreePrettyPrinter::printKey(const void* key, std::ostream *stream) const {
const char *key_ptr = static_cast<const char*>(key);
for (std::vector<attribute_id>::const_iterator subkey_it = csbtree_index_.indexed_attribute_ids_.begin();
subkey_it != csbtree_index_.indexed_attribute_ids_.end();
++subkey_it) {
const Type &subkey_type = csbtree_index_.relation_.getAttributeById(*subkey_it)->getType();
TypedValue typed_key = subkey_type.makeValue(key_ptr, csbtree_index_.key_length_bytes_);
*stream << subkey_type.printValueToString(typed_key);
if (subkey_it != csbtree_index_.indexed_attribute_ids_.end() - 1) {
*stream << ", ";
}
key_ptr += subkey_type.maximumByteLength();
}
}
void CSBTreePrettyPrinter::advanceLine(const int depth, std::ostream *stream) {
for (int print_depth = 0; print_depth < depth; ++print_depth) {
*stream << " ";
}
}
} // namespace quickstep