Coverage Report

Created: 2026-07-25 07:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibSQL/BTree.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/ByteString.h>
10
#include <AK/Function.h>
11
#include <AK/NonnullRefPtr.h>
12
#include <AK/Optional.h>
13
#include <AK/RefPtr.h>
14
#include <AK/Vector.h>
15
#include <LibCore/EventReceiver.h>
16
#include <LibSQL/Forward.h>
17
#include <LibSQL/Heap.h>
18
#include <LibSQL/Index.h>
19
#include <LibSQL/Key.h>
20
21
namespace SQL {
22
23
/**
24
 * The BTree class models a B-Tree index. It contains a collection of
25
 * Key objects organized in TreeNode objects. Keys can be inserted,
26
 * located, deleted, and the set can be traversed in sort order. All keys in
27
 * a tree have the same underlying structure. A BTree's TreeNodes and
28
 * the keys it includes are lazily loaded from the Heap when needed.
29
 *
30
 * The classes implementing the B-Tree functionality are BTree, TreeNode,
31
 * BTreeIterator, and DownPointer (a smart pointer-like helper class).
32
 */
33
class DownPointer {
34
public:
35
    explicit DownPointer(TreeNode*, Block::Index = 0);
36
    DownPointer(TreeNode*, TreeNode*);
37
    DownPointer(DownPointer&&);
38
    DownPointer(TreeNode*, DownPointer&);
39
0
    ~DownPointer() = default;
40
0
    [[nodiscard]] Block::Index block_index() const { return m_block_index; }
41
    TreeNode* node();
42
43
private:
44
    void deserialize(Serializer&);
45
46
    TreeNode* m_owner;
47
    Block::Index m_block_index { 0 };
48
    OwnPtr<TreeNode> m_node { nullptr };
49
    friend TreeNode;
50
};
51
52
class TreeNode : public IndexNode {
53
public:
54
    TreeNode(BTree&, Block::Index = 0);
55
    TreeNode(BTree&, TreeNode*, Block::Index = 0);
56
    TreeNode(BTree&, TreeNode*, TreeNode*, Block::Index = 0);
57
0
    ~TreeNode() override = default;
58
59
0
    [[nodiscard]] BTree& tree() const { return m_tree; }
60
0
    [[nodiscard]] TreeNode* up() const { return m_up; }
61
0
    [[nodiscard]] size_t size() const { return m_entries.size(); }
62
    [[nodiscard]] size_t length() const;
63
0
    [[nodiscard]] Vector<Key> entries() const { return m_entries; }
64
    [[nodiscard]] Block::Index down_pointer(size_t) const;
65
    [[nodiscard]] TreeNode* down_node(size_t);
66
0
    [[nodiscard]] bool is_leaf() const { return m_is_leaf; }
67
68
0
    Key const& operator[](size_t index) const { return m_entries[index]; }
69
    bool insert(Key const&);
70
    bool update_key_pointer(Key const&);
71
    TreeNode* node_for(Key const&);
72
    Optional<u32> get(Key&);
73
    void deserialize(Serializer&);
74
    void serialize(Serializer&) const;
75
76
private:
77
    TreeNode(BTree&, TreeNode*, DownPointer&, u32 = 0);
78
    void dump_if(int, ByteString&& = "");
79
    bool insert_in_leaf(Key const&);
80
    void just_insert(Key const&, TreeNode* = nullptr);
81
    void split();
82
    void list_node(int);
83
84
    BTree& m_tree;
85
    TreeNode* m_up;
86
    Vector<Key> m_entries;
87
    bool m_is_leaf { true };
88
    Vector<DownPointer> m_down;
89
90
    friend BTree;
91
    friend BTreeIterator;
92
};
93
94
class BTree : public Index {
95
public:
96
    static ErrorOr<NonnullRefPtr<BTree>> create(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, Block::Index);
97
    static ErrorOr<NonnullRefPtr<BTree>> create(Serializer&, NonnullRefPtr<TupleDescriptor> const&, Block::Index);
98
99
0
    Block::Index root() const { return m_root ? m_root->block_index() : 0; }
100
    bool insert(Key const&);
101
    bool update_key_pointer(Key const&);
102
    Optional<u32> get(Key&);
103
    BTreeIterator find(Key const& key);
104
    BTreeIterator begin();
105
    static BTreeIterator end();
106
    void list_tree();
107
108
    Function<void(void)> on_new_root;
109
110
private:
111
    BTree(Serializer&, NonnullRefPtr<TupleDescriptor> const&, bool unique, Block::Index);
112
    void initialize_root();
113
    TreeNode* new_root();
114
    OwnPtr<TreeNode> m_root { nullptr };
115
116
    friend BTreeIterator;
117
    friend DownPointer;
118
    friend TreeNode;
119
};
120
121
class BTreeIterator {
122
public:
123
0
    [[nodiscard]] bool is_end() const { return m_where == Where::End; }
124
0
    [[nodiscard]] size_t index() const { return m_index; }
125
    bool update(Key const&);
126
127
0
    bool operator==(BTreeIterator const& other) const { return cmp(other) == 0; }
128
0
    bool operator!=(BTreeIterator const& other) const { return cmp(other) != 0; }
129
0
    bool operator<(BTreeIterator const& other) const { return cmp(other) < 0; }
130
0
    bool operator>(BTreeIterator const& other) const { return cmp(other) > 0; }
131
0
    bool operator<=(BTreeIterator const& other) const { return cmp(other) <= 0; }
132
0
    bool operator>=(BTreeIterator const& other) const { return cmp(other) >= 0; }
133
0
    bool operator==(Key const& other) const { return cmp(other) == 0; }
134
0
    bool operator!=(Key const& other) const { return cmp(other) != 0; }
135
0
    bool operator<(Key const& other) const { return cmp(other) < 0; }
136
0
    bool operator>(Key const& other) const { return cmp(other) > 0; }
137
0
    bool operator<=(Key const& other) const { return cmp(other) <= 0; }
138
0
    bool operator>=(Key const& other) const { return cmp(other) >= 0; }
139
140
    BTreeIterator operator++()
141
0
    {
142
0
        *this = next();
143
0
        return *this;
144
0
    }
145
146
    BTreeIterator operator++(int)
147
0
    {
148
0
        *this = next();
149
0
        return *this;
150
0
    }
151
152
    BTreeIterator operator--()
153
0
    {
154
0
        *this = previous();
155
0
        return *this;
156
0
    }
157
158
    BTreeIterator const operator--(int)
159
0
    {
160
0
        *this = previous();
161
0
        return *this;
162
0
    }
163
164
    Key const& operator*() const
165
0
    {
166
0
        VERIFY(!is_end());
167
0
        return (*m_current)[m_index];
168
0
    }
169
170
    Key const& operator->() const
171
0
    {
172
0
        VERIFY(!is_end());
173
0
        return (*m_current)[m_index];
174
0
    }
175
176
    BTreeIterator& operator=(BTreeIterator const&);
177
    BTreeIterator(BTreeIterator const&) = default;
178
179
private:
180
    BTreeIterator(TreeNode*, int index);
181
0
    static BTreeIterator end() { return BTreeIterator(nullptr, -1); }
182
183
    [[nodiscard]] int cmp(BTreeIterator const&) const;
184
    [[nodiscard]] int cmp(Key const&) const;
185
    [[nodiscard]] BTreeIterator next() const;
186
    [[nodiscard]] BTreeIterator previous() const;
187
    [[nodiscard]] Key key() const;
188
189
    enum class Where {
190
        Valid,
191
        End
192
    };
193
194
    Where m_where { Where::Valid };
195
    TreeNode* m_current { nullptr };
196
    int m_index { -1 };
197
198
    friend BTree;
199
};
200
201
}