duckdb 0.8.2-dev4025.0 → 0.8.2-dev4126.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +1 -0
- package/package.json +1 -1
- package/src/duckdb/extension/json/buffered_json_reader.cpp +76 -74
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +35 -32
- package/src/duckdb/extension/json/include/json_scan.hpp +9 -6
- package/src/duckdb/extension/json/json_scan.cpp +124 -121
- package/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp +5 -0
- package/src/duckdb/src/common/radix_partitioning.cpp +1 -1
- package/src/duckdb/src/common/sort/partition_state.cpp +5 -1
- package/src/duckdb/src/core_functions/aggregate/holistic/mode.cpp +1 -1
- package/src/duckdb/src/core_functions/function_list.cpp +7 -0
- package/src/duckdb/src/core_functions/scalar/list/list_cosine_similarity.cpp +78 -0
- package/src/duckdb/src/core_functions/scalar/list/list_distance.cpp +72 -0
- package/src/duckdb/src/core_functions/scalar/list/list_inner_product.cpp +70 -0
- package/src/duckdb/src/execution/index/art/art.cpp +111 -92
- package/src/duckdb/src/execution/index/art/iterator.cpp +21 -27
- package/src/duckdb/src/execution/index/art/leaf.cpp +72 -153
- package/src/duckdb/src/execution/index/art/node.cpp +109 -203
- package/src/duckdb/src/execution/index/art/node16.cpp +32 -64
- package/src/duckdb/src/execution/index/art/node256.cpp +38 -53
- package/src/duckdb/src/execution/index/art/node4.cpp +31 -62
- package/src/duckdb/src/execution/index/art/node48.cpp +43 -65
- package/src/duckdb/src/execution/index/art/prefix.cpp +70 -141
- package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +345 -0
- package/src/duckdb/src/execution/index/fixed_size_buffer.cpp +74 -0
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +1 -1
- package/src/duckdb/src/execution/operator/schema/physical_create_art_index.cpp +1 -1
- package/src/duckdb/src/function/table/system/duckdb_columns.cpp +3 -1
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/optional_idx.hpp +1 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +51 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +17 -7
- package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +5 -5
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +10 -16
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +38 -116
- package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +17 -18
- package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +17 -23
- package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +17 -18
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +17 -24
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +16 -22
- package/src/duckdb/src/include/duckdb/execution/index/fixed_size_allocator.hpp +126 -0
- package/src/duckdb/src/include/duckdb/execution/index/fixed_size_buffer.hpp +79 -0
- package/src/duckdb/src/include/duckdb/execution/index/index_pointer.hpp +96 -0
- package/src/duckdb/src/include/duckdb/parallel/task_scheduler.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/block.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/index.hpp +10 -8
- package/src/duckdb/src/include/duckdb/storage/metadata/metadata_writer.hpp +3 -0
- package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +14 -5
- package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +2 -3
- package/src/duckdb/src/storage/checkpoint_manager.cpp +16 -21
- package/src/duckdb/src/storage/data_table.cpp +3 -3
- package/src/duckdb/src/storage/index.cpp +7 -1
- package/src/duckdb/src/storage/metadata/metadata_manager.cpp +21 -21
- package/src/duckdb/src/storage/standard_buffer_manager.cpp +0 -8
- package/src/duckdb/src/storage/storage_info.cpp +1 -1
- package/src/duckdb/src/storage/table_index_list.cpp +1 -1
- package/src/duckdb/src/transaction/commit_state.cpp +5 -1
- package/src/duckdb/ub_src_core_functions_scalar_list.cpp +6 -0
- package/src/duckdb/ub_src_execution_index.cpp +4 -0
- package/src/duckdb/ub_src_execution_index_art.cpp +0 -2
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +0 -238
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +0 -115
@@ -7,34 +7,34 @@
|
|
7
7
|
|
8
8
|
namespace duckdb {
|
9
9
|
|
10
|
-
bool IteratorKey::operator>(const ARTKey &
|
11
|
-
for (idx_t i = 0; i < MinValue<idx_t>(key_bytes.size(),
|
12
|
-
if (key_bytes[i] >
|
10
|
+
bool IteratorKey::operator>(const ARTKey &key) const {
|
11
|
+
for (idx_t i = 0; i < MinValue<idx_t>(key_bytes.size(), key.len); i++) {
|
12
|
+
if (key_bytes[i] > key.data[i]) {
|
13
13
|
return true;
|
14
|
-
} else if (key_bytes[i] <
|
14
|
+
} else if (key_bytes[i] < key.data[i]) {
|
15
15
|
return false;
|
16
16
|
}
|
17
17
|
}
|
18
|
-
return key_bytes.size() >
|
18
|
+
return key_bytes.size() > key.len;
|
19
19
|
}
|
20
20
|
|
21
|
-
bool IteratorKey::operator>=(const ARTKey &
|
22
|
-
for (idx_t i = 0; i < MinValue<idx_t>(key_bytes.size(),
|
23
|
-
if (key_bytes[i] >
|
21
|
+
bool IteratorKey::operator>=(const ARTKey &key) const {
|
22
|
+
for (idx_t i = 0; i < MinValue<idx_t>(key_bytes.size(), key.len); i++) {
|
23
|
+
if (key_bytes[i] > key.data[i]) {
|
24
24
|
return true;
|
25
|
-
} else if (key_bytes[i] <
|
25
|
+
} else if (key_bytes[i] < key.data[i]) {
|
26
26
|
return false;
|
27
27
|
}
|
28
28
|
}
|
29
|
-
return key_bytes.size() >=
|
29
|
+
return key_bytes.size() >= key.len;
|
30
30
|
}
|
31
31
|
|
32
|
-
bool IteratorKey::operator==(const ARTKey &
|
32
|
+
bool IteratorKey::operator==(const ARTKey &key) const {
|
33
33
|
// NOTE: we only use this for finding the LowerBound, in which case the length
|
34
34
|
// has to be equal
|
35
|
-
D_ASSERT(key_bytes.size() ==
|
35
|
+
D_ASSERT(key_bytes.size() == key.len);
|
36
36
|
for (idx_t i = 0; i < key_bytes.size(); i++) {
|
37
|
-
if (key_bytes[i] !=
|
37
|
+
if (key_bytes[i] != key.data[i]) {
|
38
38
|
return false;
|
39
39
|
}
|
40
40
|
}
|
@@ -71,12 +71,9 @@ bool Iterator::Scan(const ARTKey &upper_bound, const idx_t max_count, vector<row
|
|
71
71
|
return true;
|
72
72
|
}
|
73
73
|
|
74
|
-
void Iterator::FindMinimum(Node &node) {
|
74
|
+
void Iterator::FindMinimum(const Node &node) {
|
75
75
|
|
76
|
-
D_ASSERT(node.
|
77
|
-
if (node.IsSerialized()) {
|
78
|
-
node.Deserialize(*art);
|
79
|
-
}
|
76
|
+
D_ASSERT(node.HasMetadata());
|
80
77
|
|
81
78
|
// found the minimum
|
82
79
|
if (node.GetType() == NType::LEAF || node.GetType() == NType::LEAF_INLINED) {
|
@@ -86,7 +83,7 @@ void Iterator::FindMinimum(Node &node) {
|
|
86
83
|
|
87
84
|
// traverse the prefix
|
88
85
|
if (node.GetType() == NType::PREFIX) {
|
89
|
-
auto &prefix = Prefix
|
86
|
+
auto &prefix = Node::Ref<const Prefix>(*art, node, NType::PREFIX);
|
90
87
|
for (idx_t i = 0; i < prefix.data[Node::PREFIX_SIZE]; i++) {
|
91
88
|
current_key.Push(prefix.data[i]);
|
92
89
|
}
|
@@ -103,16 +100,12 @@ void Iterator::FindMinimum(Node &node) {
|
|
103
100
|
FindMinimum(*next);
|
104
101
|
}
|
105
102
|
|
106
|
-
bool Iterator::LowerBound(Node &node, const ARTKey &key, const bool equal, idx_t depth) {
|
103
|
+
bool Iterator::LowerBound(const Node &node, const ARTKey &key, const bool equal, idx_t depth) {
|
107
104
|
|
108
|
-
if (!node.
|
105
|
+
if (!node.HasMetadata()) {
|
109
106
|
return false;
|
110
107
|
}
|
111
108
|
|
112
|
-
if (node.IsSerialized()) {
|
113
|
-
node.Deserialize(*art);
|
114
|
-
}
|
115
|
-
|
116
109
|
// we found the lower bound
|
117
110
|
if (node.GetType() == NType::LEAF || node.GetType() == NType::LEAF_INLINED) {
|
118
111
|
if (!equal && current_key == key) {
|
@@ -145,7 +138,7 @@ bool Iterator::LowerBound(Node &node, const ARTKey &key, const bool equal, idx_t
|
|
145
138
|
}
|
146
139
|
|
147
140
|
// resolve the prefix
|
148
|
-
auto &prefix = Prefix
|
141
|
+
auto &prefix = Node::Ref<const Prefix>(*art, node, NType::PREFIX);
|
149
142
|
for (idx_t i = 0; i < prefix.data[Node::PREFIX_SIZE]; i++) {
|
150
143
|
current_key.Push(prefix.data[i]);
|
151
144
|
}
|
@@ -206,7 +199,8 @@ bool Iterator::Next() {
|
|
206
199
|
|
207
200
|
void Iterator::PopNode() {
|
208
201
|
if (nodes.top().node.GetType() == NType::PREFIX) {
|
209
|
-
auto
|
202
|
+
auto &prefix = Node::Ref<const Prefix>(*art, nodes.top().node, NType::PREFIX);
|
203
|
+
auto prefix_byte_count = prefix.data[Node::PREFIX_SIZE];
|
210
204
|
current_key.Pop(prefix_byte_count);
|
211
205
|
} else {
|
212
206
|
current_key.Pop(1);
|
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
#include "duckdb/execution/index/art/art.hpp"
|
4
4
|
#include "duckdb/execution/index/art/node.hpp"
|
5
|
-
#include "duckdb/storage/metadata/metadata_reader.hpp"
|
6
|
-
#include "duckdb/storage/metadata/metadata_writer.hpp"
|
7
5
|
|
8
6
|
namespace duckdb {
|
9
7
|
|
@@ -11,8 +9,8 @@ void Leaf::New(Node &node, const row_t row_id) {
|
|
11
9
|
|
12
10
|
// we directly inline this row ID into the node pointer
|
13
11
|
D_ASSERT(row_id < MAX_ROW_ID_LOCAL);
|
14
|
-
node.
|
15
|
-
node.
|
12
|
+
node.Clear();
|
13
|
+
node.SetMetadata(static_cast<uint8_t>(NType::LEAF_INLINED));
|
16
14
|
node.SetRowId(row_id);
|
17
15
|
}
|
18
16
|
|
@@ -23,9 +21,9 @@ void Leaf::New(ART &art, reference<Node> &node, const row_t *row_ids, idx_t coun
|
|
23
21
|
idx_t copy_count = 0;
|
24
22
|
while (count) {
|
25
23
|
node.get() = Node::GetAllocator(art, NType::LEAF).New();
|
26
|
-
node.get().
|
24
|
+
node.get().SetMetadata(static_cast<uint8_t>(NType::LEAF));
|
27
25
|
|
28
|
-
auto &leaf = Leaf
|
26
|
+
auto &leaf = Node::RefMutable<Leaf>(art, node, NType::LEAF);
|
29
27
|
|
30
28
|
leaf.count = MinValue((idx_t)Node::LEAF_SIZE, count);
|
31
29
|
for (idx_t i = 0; i < leaf.count; i++) {
|
@@ -36,7 +34,7 @@ void Leaf::New(ART &art, reference<Node> &node, const row_t *row_ids, idx_t coun
|
|
36
34
|
count -= leaf.count;
|
37
35
|
|
38
36
|
node = leaf.ptr;
|
39
|
-
leaf.ptr.
|
37
|
+
leaf.ptr.Clear();
|
40
38
|
}
|
41
39
|
}
|
42
40
|
|
@@ -44,40 +42,39 @@ void Leaf::Free(ART &art, Node &node) {
|
|
44
42
|
|
45
43
|
Node current_node = node;
|
46
44
|
Node next_node;
|
47
|
-
while (current_node.
|
48
|
-
next_node = Leaf
|
45
|
+
while (current_node.HasMetadata()) {
|
46
|
+
next_node = Node::RefMutable<Leaf>(art, current_node, NType::LEAF).ptr;
|
49
47
|
Node::GetAllocator(art, NType::LEAF).Free(current_node);
|
50
48
|
current_node = next_node;
|
51
49
|
}
|
52
50
|
|
53
|
-
node.
|
51
|
+
node.Clear();
|
54
52
|
}
|
55
53
|
|
56
54
|
void Leaf::InitializeMerge(ART &art, Node &node, const ARTFlags &flags) {
|
57
55
|
|
58
|
-
auto merge_buffer_count = flags.merge_buffer_counts[(
|
56
|
+
auto merge_buffer_count = flags.merge_buffer_counts[static_cast<uint8_t>(NType::LEAF) - 1];
|
59
57
|
|
60
58
|
Node next_node = node;
|
61
|
-
node.
|
59
|
+
node.IncreaseBufferId(merge_buffer_count);
|
62
60
|
|
63
|
-
while (next_node.
|
64
|
-
auto &leaf = Leaf
|
61
|
+
while (next_node.HasMetadata()) {
|
62
|
+
auto &leaf = Node::RefMutable<Leaf>(art, next_node, NType::LEAF);
|
65
63
|
next_node = leaf.ptr;
|
66
|
-
if (leaf.ptr.
|
67
|
-
leaf.ptr.
|
64
|
+
if (leaf.ptr.HasMetadata()) {
|
65
|
+
leaf.ptr.IncreaseBufferId(merge_buffer_count);
|
68
66
|
}
|
69
67
|
}
|
70
68
|
}
|
71
69
|
|
72
70
|
void Leaf::Merge(ART &art, Node &l_node, Node &r_node) {
|
73
71
|
|
74
|
-
D_ASSERT(l_node.
|
75
|
-
D_ASSERT(r_node.IsSet() && !r_node.IsSerialized());
|
72
|
+
D_ASSERT(l_node.HasMetadata() && r_node.HasMetadata());
|
76
73
|
|
77
74
|
// copy inlined row ID of r_node
|
78
75
|
if (r_node.GetType() == NType::LEAF_INLINED) {
|
79
|
-
|
80
|
-
r_node.
|
76
|
+
Insert(art, l_node, r_node.GetRowId());
|
77
|
+
r_node.Clear();
|
81
78
|
return;
|
82
79
|
}
|
83
80
|
|
@@ -85,8 +82,8 @@ void Leaf::Merge(ART &art, Node &l_node, Node &r_node) {
|
|
85
82
|
if (l_node.GetType() == NType::LEAF_INLINED) {
|
86
83
|
auto row_id = l_node.GetRowId();
|
87
84
|
l_node = r_node;
|
88
|
-
|
89
|
-
r_node.
|
85
|
+
Insert(art, l_node, row_id);
|
86
|
+
r_node.Clear();
|
90
87
|
return;
|
91
88
|
}
|
92
89
|
|
@@ -94,33 +91,33 @@ void Leaf::Merge(ART &art, Node &l_node, Node &r_node) {
|
|
94
91
|
D_ASSERT(r_node.GetType() != NType::LEAF_INLINED);
|
95
92
|
|
96
93
|
reference<Node> l_node_ref(l_node);
|
97
|
-
reference<Leaf> l_leaf = Leaf
|
94
|
+
reference<Leaf> l_leaf = Node::RefMutable<Leaf>(art, l_node_ref, NType::LEAF);
|
98
95
|
|
99
96
|
// find a non-full node
|
100
97
|
while (l_leaf.get().count == Node::LEAF_SIZE) {
|
101
98
|
l_node_ref = l_leaf.get().ptr;
|
102
99
|
|
103
100
|
// the last leaf is full
|
104
|
-
if (!l_leaf.get().ptr.
|
101
|
+
if (!l_leaf.get().ptr.HasMetadata()) {
|
105
102
|
break;
|
106
103
|
}
|
107
|
-
l_leaf = Leaf
|
104
|
+
l_leaf = Node::RefMutable<Leaf>(art, l_node_ref, NType::LEAF);
|
108
105
|
}
|
109
106
|
|
110
107
|
// store the last leaf and then append r_node
|
111
108
|
auto last_leaf_node = l_node_ref.get();
|
112
109
|
l_node_ref.get() = r_node;
|
113
|
-
r_node.
|
110
|
+
r_node.Clear();
|
114
111
|
|
115
112
|
// append the remaining row IDs of the last leaf node
|
116
|
-
if (last_leaf_node.
|
113
|
+
if (last_leaf_node.HasMetadata()) {
|
117
114
|
// find the tail
|
118
|
-
l_leaf = Leaf
|
119
|
-
while (l_leaf.get().ptr.
|
120
|
-
l_leaf = Leaf
|
115
|
+
l_leaf = Node::RefMutable<Leaf>(art, l_node_ref, NType::LEAF);
|
116
|
+
while (l_leaf.get().ptr.HasMetadata()) {
|
117
|
+
l_leaf = Node::RefMutable<Leaf>(art, l_leaf.get().ptr, NType::LEAF);
|
121
118
|
}
|
122
119
|
// append the row IDs
|
123
|
-
auto &last_leaf = Leaf
|
120
|
+
auto &last_leaf = Node::RefMutable<Leaf>(art, last_leaf_node, NType::LEAF);
|
124
121
|
for (idx_t i = 0; i < last_leaf.count; i++) {
|
125
122
|
l_leaf = l_leaf.get().Append(art, last_leaf.row_ids[i]);
|
126
123
|
}
|
@@ -130,28 +127,25 @@ void Leaf::Merge(ART &art, Node &l_node, Node &r_node) {
|
|
130
127
|
|
131
128
|
void Leaf::Insert(ART &art, Node &node, const row_t row_id) {
|
132
129
|
|
133
|
-
D_ASSERT(node.
|
130
|
+
D_ASSERT(node.HasMetadata());
|
134
131
|
|
135
132
|
if (node.GetType() == NType::LEAF_INLINED) {
|
136
|
-
|
137
|
-
|
133
|
+
MoveInlinedToLeaf(art, node);
|
134
|
+
Insert(art, node, row_id);
|
138
135
|
return;
|
139
136
|
}
|
140
137
|
|
141
138
|
// append to the tail
|
142
|
-
reference<Leaf> leaf = Leaf
|
143
|
-
while (leaf.get().ptr.
|
144
|
-
|
145
|
-
leaf.get().ptr.Deserialize(art);
|
146
|
-
}
|
147
|
-
leaf = Leaf::Get(art, leaf.get().ptr);
|
139
|
+
reference<Leaf> leaf = Node::RefMutable<Leaf>(art, node, NType::LEAF);
|
140
|
+
while (leaf.get().ptr.HasMetadata()) {
|
141
|
+
leaf = Node::RefMutable<Leaf>(art, leaf.get().ptr, NType::LEAF);
|
148
142
|
}
|
149
143
|
leaf.get().Append(art, row_id);
|
150
144
|
}
|
151
145
|
|
152
146
|
bool Leaf::Remove(ART &art, reference<Node> &node, const row_t row_id) {
|
153
147
|
|
154
|
-
D_ASSERT(node.get().
|
148
|
+
D_ASSERT(node.get().HasMetadata());
|
155
149
|
|
156
150
|
if (node.get().GetType() == NType::LEAF_INLINED) {
|
157
151
|
if (node.get().GetRowId() == row_id) {
|
@@ -160,14 +154,14 @@ bool Leaf::Remove(ART &art, reference<Node> &node, const row_t row_id) {
|
|
160
154
|
return false;
|
161
155
|
}
|
162
156
|
|
163
|
-
reference<Leaf> leaf = Leaf
|
157
|
+
reference<Leaf> leaf = Node::RefMutable<Leaf>(art, node, NType::LEAF);
|
164
158
|
|
165
159
|
// inline the remaining row ID
|
166
160
|
if (leaf.get().count == 2) {
|
167
161
|
if (leaf.get().row_ids[0] == row_id || leaf.get().row_ids[1] == row_id) {
|
168
162
|
auto remaining_row_id = leaf.get().row_ids[0] == row_id ? leaf.get().row_ids[1] : leaf.get().row_ids[0];
|
169
163
|
Node::Free(art, node);
|
170
|
-
|
164
|
+
New(node, remaining_row_id);
|
171
165
|
}
|
172
166
|
return false;
|
173
167
|
}
|
@@ -177,12 +171,9 @@ bool Leaf::Remove(ART &art, reference<Node> &node, const row_t row_id) {
|
|
177
171
|
|
178
172
|
// go to the tail and keep track of the previous leaf node
|
179
173
|
reference<Leaf> prev_leaf(leaf);
|
180
|
-
while (leaf.get().ptr.
|
174
|
+
while (leaf.get().ptr.HasMetadata()) {
|
181
175
|
prev_leaf = leaf;
|
182
|
-
|
183
|
-
leaf.get().ptr.Deserialize(art);
|
184
|
-
}
|
185
|
-
leaf = Leaf::Get(art, leaf.get().ptr);
|
176
|
+
leaf = Node::RefMutable<Leaf>(art, leaf.get().ptr, NType::LEAF);
|
186
177
|
}
|
187
178
|
|
188
179
|
auto last_idx = leaf.get().count;
|
@@ -199,9 +190,8 @@ bool Leaf::Remove(ART &art, reference<Node> &node, const row_t row_id) {
|
|
199
190
|
}
|
200
191
|
|
201
192
|
// find the row ID and copy the last row ID to that position
|
202
|
-
while (node.get().
|
203
|
-
|
204
|
-
leaf = Leaf::Get(art, node);
|
193
|
+
while (node.get().HasMetadata()) {
|
194
|
+
leaf = Node::RefMutable<Leaf>(art, node, NType::LEAF);
|
205
195
|
for (idx_t i = 0; i < leaf.get().count; i++) {
|
206
196
|
if (leaf.get().row_ids[i] == row_id) {
|
207
197
|
leaf.get().row_ids[i] = last_row_id;
|
@@ -213,54 +203,43 @@ bool Leaf::Remove(ART &art, reference<Node> &node, const row_t row_id) {
|
|
213
203
|
return false;
|
214
204
|
}
|
215
205
|
|
216
|
-
idx_t Leaf::TotalCount(ART &art, Node &node) {
|
217
|
-
|
218
|
-
// NOTE: first leaf in the leaf chain is already deserialized
|
219
|
-
D_ASSERT(node.IsSet() && !node.IsSerialized());
|
206
|
+
idx_t Leaf::TotalCount(ART &art, const Node &node) {
|
220
207
|
|
208
|
+
D_ASSERT(node.HasMetadata());
|
221
209
|
if (node.GetType() == NType::LEAF_INLINED) {
|
222
210
|
return 1;
|
223
211
|
}
|
224
212
|
|
225
213
|
idx_t count = 0;
|
226
|
-
reference<Node> node_ref(node);
|
227
|
-
while (node_ref.get().
|
228
|
-
auto &leaf = Leaf
|
214
|
+
reference<const Node> node_ref(node);
|
215
|
+
while (node_ref.get().HasMetadata()) {
|
216
|
+
auto &leaf = Node::Ref<const Leaf>(art, node_ref, NType::LEAF);
|
229
217
|
count += leaf.count;
|
230
|
-
|
231
|
-
if (leaf.ptr.IsSerialized()) {
|
232
|
-
leaf.ptr.Deserialize(art);
|
233
|
-
}
|
234
218
|
node_ref = leaf.ptr;
|
235
219
|
}
|
236
220
|
return count;
|
237
221
|
}
|
238
222
|
|
239
|
-
bool Leaf::GetRowIds(ART &art, Node &node, vector<row_t> &result_ids, idx_t max_count) {
|
223
|
+
bool Leaf::GetRowIds(ART &art, const Node &node, vector<row_t> &result_ids, idx_t max_count) {
|
240
224
|
|
241
225
|
// adding more elements would exceed the maximum count
|
242
|
-
D_ASSERT(node.
|
243
|
-
if (result_ids.size() +
|
226
|
+
D_ASSERT(node.HasMetadata());
|
227
|
+
if (result_ids.size() + TotalCount(art, node) > max_count) {
|
244
228
|
return false;
|
245
229
|
}
|
246
230
|
|
247
|
-
// NOTE: Leaf::TotalCount fully deserializes the leaf
|
248
|
-
D_ASSERT(!node.IsSerialized());
|
249
|
-
|
250
231
|
if (node.GetType() == NType::LEAF_INLINED) {
|
251
232
|
// push back the inlined row ID of this leaf
|
252
233
|
result_ids.push_back(node.GetRowId());
|
253
234
|
|
254
235
|
} else {
|
255
236
|
// push back all the row IDs of this leaf
|
256
|
-
reference<Node> last_leaf_ref(node);
|
257
|
-
while (last_leaf_ref.get().
|
258
|
-
auto &leaf = Leaf
|
237
|
+
reference<const Node> last_leaf_ref(node);
|
238
|
+
while (last_leaf_ref.get().HasMetadata()) {
|
239
|
+
auto &leaf = Node::Ref<const Leaf>(art, last_leaf_ref, NType::LEAF);
|
259
240
|
for (idx_t i = 0; i < leaf.count; i++) {
|
260
241
|
result_ids.push_back(leaf.row_ids[i]);
|
261
242
|
}
|
262
|
-
|
263
|
-
D_ASSERT(!leaf.ptr.IsSerialized());
|
264
243
|
last_leaf_ref = leaf.ptr;
|
265
244
|
}
|
266
245
|
}
|
@@ -268,45 +247,40 @@ bool Leaf::GetRowIds(ART &art, Node &node, vector<row_t> &result_ids, idx_t max_
|
|
268
247
|
return true;
|
269
248
|
}
|
270
249
|
|
271
|
-
bool Leaf::ContainsRowId(ART &art, Node &node, const row_t row_id) {
|
250
|
+
bool Leaf::ContainsRowId(ART &art, const Node &node, const row_t row_id) {
|
272
251
|
|
273
|
-
|
274
|
-
// last row ID at a different position) or inserted a row ID into this leaf
|
275
|
-
// (at the end), so the whole leaf is deserialized
|
276
|
-
D_ASSERT(node.IsSet() && !node.IsSerialized());
|
252
|
+
D_ASSERT(node.HasMetadata());
|
277
253
|
|
278
254
|
if (node.GetType() == NType::LEAF_INLINED) {
|
279
255
|
return node.GetRowId() == row_id;
|
280
256
|
}
|
281
257
|
|
282
|
-
reference<Node> ref_node(node);
|
283
|
-
while (ref_node.get().
|
284
|
-
auto &leaf = Leaf
|
258
|
+
reference<const Node> ref_node(node);
|
259
|
+
while (ref_node.get().HasMetadata()) {
|
260
|
+
auto &leaf = Node::Ref<const Leaf>(art, ref_node, NType::LEAF);
|
285
261
|
for (idx_t i = 0; i < leaf.count; i++) {
|
286
262
|
if (leaf.row_ids[i] == row_id) {
|
287
263
|
return true;
|
288
264
|
}
|
289
265
|
}
|
290
|
-
|
291
|
-
D_ASSERT(!leaf.ptr.IsSerialized());
|
292
266
|
ref_node = leaf.ptr;
|
293
267
|
}
|
294
268
|
|
295
269
|
return false;
|
296
270
|
}
|
297
271
|
|
298
|
-
string Leaf::VerifyAndToString(ART &art, Node &node) {
|
272
|
+
string Leaf::VerifyAndToString(ART &art, const Node &node, const bool only_verify) {
|
299
273
|
|
300
274
|
if (node.GetType() == NType::LEAF_INLINED) {
|
301
|
-
return "Leaf [count: 1, row ID: " + to_string(node.GetRowId()) + "]";
|
275
|
+
return only_verify ? "" : "Leaf [count: 1, row ID: " + to_string(node.GetRowId()) + "]";
|
302
276
|
}
|
303
277
|
|
304
278
|
string str = "";
|
305
279
|
|
306
|
-
reference<Node> node_ref(node);
|
307
|
-
while (node_ref.get().
|
280
|
+
reference<const Node> node_ref(node);
|
281
|
+
while (node_ref.get().HasMetadata()) {
|
308
282
|
|
309
|
-
auto &leaf = Leaf
|
283
|
+
auto &leaf = Node::Ref<const Leaf>(art, node_ref, NType::LEAF);
|
310
284
|
D_ASSERT(leaf.count <= Node::LEAF_SIZE);
|
311
285
|
|
312
286
|
str += "Leaf [count: " + to_string(leaf.count) + ", row IDs: ";
|
@@ -315,64 +289,9 @@ string Leaf::VerifyAndToString(ART &art, Node &node) {
|
|
315
289
|
}
|
316
290
|
str += "] ";
|
317
291
|
|
318
|
-
// NOTE: we are currently only calling this function during CREATE INDEX
|
319
|
-
// statements (and debugging), so the index is never serialized
|
320
|
-
D_ASSERT(!leaf.ptr.IsSerialized());
|
321
292
|
node_ref = leaf.ptr;
|
322
293
|
}
|
323
|
-
return str;
|
324
|
-
}
|
325
|
-
|
326
|
-
BlockPointer Leaf::Serialize(ART &art, Node &node, MetadataWriter &writer) {
|
327
|
-
|
328
|
-
if (node.GetType() == NType::LEAF_INLINED) {
|
329
|
-
auto block_pointer = writer.GetBlockPointer();
|
330
|
-
writer.Write(NType::LEAF_INLINED);
|
331
|
-
writer.Write(node.GetRowId());
|
332
|
-
return block_pointer;
|
333
|
-
}
|
334
|
-
|
335
|
-
auto block_pointer = writer.GetBlockPointer();
|
336
|
-
writer.Write(NType::LEAF);
|
337
|
-
idx_t total_count = Leaf::TotalCount(art, node);
|
338
|
-
writer.Write<idx_t>(total_count);
|
339
|
-
|
340
|
-
// iterate all leaves and write their row IDs
|
341
|
-
reference<Node> ref_node(node);
|
342
|
-
while (ref_node.get().IsSet()) {
|
343
|
-
D_ASSERT(!ref_node.get().IsSerialized());
|
344
|
-
auto &leaf = Leaf::Get(art, ref_node);
|
345
|
-
|
346
|
-
// write row IDs
|
347
|
-
for (idx_t i = 0; i < leaf.count; i++) {
|
348
|
-
writer.Write(leaf.row_ids[i]);
|
349
|
-
}
|
350
|
-
ref_node = leaf.ptr;
|
351
|
-
}
|
352
|
-
|
353
|
-
return block_pointer;
|
354
|
-
}
|
355
|
-
|
356
|
-
void Leaf::Deserialize(ART &art, Node &node, MetadataReader &reader) {
|
357
|
-
|
358
|
-
auto total_count = reader.Read<idx_t>();
|
359
|
-
reference<Node> ref_node(node);
|
360
|
-
|
361
|
-
while (total_count) {
|
362
|
-
ref_node.get() = Node::GetAllocator(art, NType::LEAF).New();
|
363
|
-
ref_node.get().SetType((uint8_t)NType::LEAF);
|
364
|
-
|
365
|
-
auto &leaf = Leaf::Get(art, ref_node);
|
366
|
-
|
367
|
-
leaf.count = MinValue((idx_t)Node::LEAF_SIZE, total_count);
|
368
|
-
for (idx_t i = 0; i < leaf.count; i++) {
|
369
|
-
leaf.row_ids[i] = reader.Read<row_t>();
|
370
|
-
}
|
371
|
-
|
372
|
-
total_count -= leaf.count;
|
373
|
-
ref_node = leaf.ptr;
|
374
|
-
leaf.ptr.Reset();
|
375
|
-
}
|
294
|
+
return only_verify ? "" : str;
|
376
295
|
}
|
377
296
|
|
378
297
|
void Leaf::Vacuum(ART &art, Node &node) {
|
@@ -380,12 +299,12 @@ void Leaf::Vacuum(ART &art, Node &node) {
|
|
380
299
|
auto &allocator = Node::GetAllocator(art, NType::LEAF);
|
381
300
|
|
382
301
|
reference<Node> node_ref(node);
|
383
|
-
while (node_ref.get().
|
302
|
+
while (node_ref.get().HasMetadata()) {
|
384
303
|
if (allocator.NeedsVacuum(node_ref)) {
|
385
304
|
node_ref.get() = allocator.VacuumPointer(node_ref);
|
386
|
-
node_ref.get().
|
305
|
+
node_ref.get().SetMetadata(static_cast<uint8_t>(NType::LEAF));
|
387
306
|
}
|
388
|
-
auto &leaf = Leaf
|
307
|
+
auto &leaf = Node::RefMutable<Leaf>(art, node_ref, NType::LEAF);
|
389
308
|
node_ref = leaf.ptr;
|
390
309
|
}
|
391
310
|
}
|
@@ -395,12 +314,12 @@ void Leaf::MoveInlinedToLeaf(ART &art, Node &node) {
|
|
395
314
|
D_ASSERT(node.GetType() == NType::LEAF_INLINED);
|
396
315
|
auto row_id = node.GetRowId();
|
397
316
|
node = Node::GetAllocator(art, NType::LEAF).New();
|
398
|
-
node.
|
317
|
+
node.SetMetadata(static_cast<uint8_t>(NType::LEAF));
|
399
318
|
|
400
|
-
auto &leaf = Leaf
|
319
|
+
auto &leaf = Node::RefMutable<Leaf>(art, node, NType::LEAF);
|
401
320
|
leaf.count = 1;
|
402
321
|
leaf.row_ids[0] = row_id;
|
403
|
-
leaf.ptr.
|
322
|
+
leaf.ptr.Clear();
|
404
323
|
}
|
405
324
|
|
406
325
|
Leaf &Leaf::Append(ART &art, const row_t row_id) {
|
@@ -410,11 +329,11 @@ Leaf &Leaf::Append(ART &art, const row_t row_id) {
|
|
410
329
|
// we need a new leaf node
|
411
330
|
if (leaf.get().count == Node::LEAF_SIZE) {
|
412
331
|
leaf.get().ptr = Node::GetAllocator(art, NType::LEAF).New();
|
413
|
-
leaf.get().ptr.
|
332
|
+
leaf.get().ptr.SetMetadata(static_cast<uint8_t>(NType::LEAF));
|
414
333
|
|
415
|
-
leaf = Leaf
|
334
|
+
leaf = Node::RefMutable<Leaf>(art, leaf.get().ptr, NType::LEAF);
|
416
335
|
leaf.get().count = 0;
|
417
|
-
leaf.get().ptr.
|
336
|
+
leaf.get().ptr.Clear();
|
418
337
|
}
|
419
338
|
|
420
339
|
leaf.get().row_ids[leaf.get().count] = row_id;
|