aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/test/btree/btree_printer.h
blob: 8430dc894baaad39947ee830a6bbc2978438377d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "data_printer.h"
#include "aggregated_printer.h"
#include <vespa/vespalib/btree/btreenodeallocator.h>

namespace vespalib::btree::test {

template <typename ostream, typename NodeAllocator>
class BTreePrinter
{
    using LeafNode = typename NodeAllocator::LeafNodeType;
    using InternalNode = typename NodeAllocator::InternalNodeType;
    ostream &_os;
    const NodeAllocator &_allocator;
    bool _levelFirst;
    uint8_t _printLevel;

    void printLeafNode(const LeafNode &n) {
        if (!_levelFirst) {
            _os << ",";
        }
        _levelFirst = false;
        _os << "{";
        for (uint32_t i = 0; i < n.validSlots(); ++i) {
            if (i > 0) _os << ",";
            _os << n.getKey(i) << ":" << n.getData(i);
        }
        printAggregated(_os, n.getAggregated());
        _os << "}";
    }

    void printInternalNode(const InternalNode &n) {
        if (!_levelFirst) {
            _os << ",";
        }
        _levelFirst = false;
        _os << "{";
        for (uint32_t i = 0; i < n.validSlots(); ++i) {
            if (i > 0) _os << ",";
            _os << n.getKey(i);
        }
        printAggregated(_os, n.getAggregated());
        _os << "}";
    }

    void printNode(BTreeNode::Ref ref) {
        if (!ref.valid()) {
            _os << "[]";
        }
        if (_allocator.isLeafRef(ref)) {
            printLeafNode(*_allocator.mapLeafRef(ref));
            return;
        }
        const InternalNode &n(*_allocator.mapInternalRef(ref));
        if (n.getLevel() == _printLevel) {
            printInternalNode(n);
            return;
        }
        for (uint32_t i = 0; i < n.validSlots(); ++i) {
            printNode(n.getChild(i));
        }
    }

public:

    BTreePrinter(ostream &os, const NodeAllocator &allocator)
        : _os(os),
          _allocator(allocator),
          _levelFirst(true),
          _printLevel(0)
    {
    }

    ~BTreePrinter() { }

    void print(BTreeNode::Ref ref) {
        if (!ref.valid()) {
            _os << "{}";
            return;
        }
        _printLevel = 0;
        if (!_allocator.isLeafRef(ref)) {
            const InternalNode &n(*_allocator.mapInternalRef(ref));
            _printLevel = n.getLevel();
        }
        while (_printLevel > 0) {
            _os << "{";
            _levelFirst = true;
            printNode(ref);
            _os << "} -> ";
            --_printLevel;
        }
        _os << "{";
        _levelFirst = true;
        printNode(ref);
        _os << "}";
    }
};

} // namespace vespalib::btree::test