duckdb 0.8.2-dev1764.0 → 0.8.2-dev1859.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/README.md +7 -0
- package/binding.gyp +1 -0
- package/package.json +1 -1
- package/src/duckdb/extension/parquet/include/parquet_reader.hpp +1 -0
- package/src/duckdb/extension/parquet/parquet_extension.cpp +38 -22
- package/src/duckdb/extension/parquet/parquet_reader.cpp +1 -4
- package/src/duckdb/src/common/constants.cpp +2 -1
- package/src/duckdb/src/common/enum_util.cpp +5 -5
- package/src/duckdb/src/common/sort/sort_state.cpp +1 -1
- package/src/duckdb/src/common/sort/sorted_block.cpp +1 -1
- package/src/duckdb/src/common/types/column/column_data_collection.cpp +8 -0
- package/src/duckdb/src/common/types/column/column_data_collection_segment.cpp +5 -0
- package/src/duckdb/src/common/types/string_heap.cpp +4 -0
- package/src/duckdb/src/core_functions/function_list.cpp +2 -0
- package/src/duckdb/src/core_functions/scalar/debug/vector_type.cpp +23 -0
- package/src/duckdb/src/execution/index/art/art.cpp +49 -108
- package/src/duckdb/src/execution/index/art/art_key.cpp +0 -11
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +10 -14
- package/src/duckdb/src/execution/index/art/iterator.cpp +13 -19
- package/src/duckdb/src/execution/index/art/leaf.cpp +290 -241
- package/src/duckdb/src/execution/index/art/node.cpp +104 -95
- package/src/duckdb/src/execution/index/art/node16.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node256.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node4.cpp +6 -6
- package/src/duckdb/src/execution/index/art/node48.cpp +6 -6
- package/src/duckdb/src/execution/index/art/prefix.cpp +49 -39
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +34 -1175
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +4 -14
- package/src/duckdb/src/execution/window_executor.cpp +1280 -0
- package/src/duckdb/src/execution/window_segment_tree.cpp +224 -117
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/constants.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/type_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/typedefs.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_allocator.hpp +10 -0
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_collection.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_collection_segment.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/types/string_heap.hpp +3 -0
- package/src/duckdb/src/include/duckdb/core_functions/scalar/debug_functions.hpp +27 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +0 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +22 -24
- package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +43 -40
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +119 -40
- package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +4 -2
- package/src/duckdb/src/include/duckdb/execution/window_executor.hpp +313 -0
- package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +60 -53
- package/src/duckdb/src/include/duckdb/storage/arena_allocator.hpp +1 -0
- package/src/duckdb/src/parser/parser.cpp +43 -38
- package/src/duckdb/src/storage/arena_allocator.cpp +12 -0
- package/src/duckdb/src/storage/compression/rle.cpp +52 -12
- package/src/duckdb/ub_src_core_functions_scalar_debug.cpp +2 -0
- package/src/duckdb/ub_src_execution.cpp +2 -0
- package/src/duckdb/ub_src_execution_index_art.cpp +0 -4
- package/src/duckdb/src/execution/index/art/leaf_segment.cpp +0 -52
- package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +0 -22
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +0 -38
- package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +0 -58
@@ -8,7 +8,6 @@
|
|
8
8
|
#include "duckdb/execution/index/art/node16.hpp"
|
9
9
|
#include "duckdb/execution/index/art/node4.hpp"
|
10
10
|
#include "duckdb/execution/index/art/leaf.hpp"
|
11
|
-
#include "duckdb/execution/index/art/leaf_segment.hpp"
|
12
11
|
#include "duckdb/execution/index/art/prefix.hpp"
|
13
12
|
#include "duckdb/storage/meta_block_reader.hpp"
|
14
13
|
#include "duckdb/storage/meta_block_writer.hpp"
|
@@ -20,12 +19,24 @@ namespace duckdb {
|
|
20
19
|
// Constructors / Destructors
|
21
20
|
//===--------------------------------------------------------------------===//
|
22
21
|
|
23
|
-
Node::Node(
|
24
|
-
|
22
|
+
Node::Node(MetaBlockReader &reader) {
|
23
|
+
|
24
|
+
idx_t block_id = reader.Read<block_id_t>();
|
25
|
+
auto offset = reader.Read<uint32_t>();
|
26
|
+
Reset();
|
27
|
+
|
28
|
+
if (block_id == DConstants::INVALID_INDEX) {
|
29
|
+
return;
|
30
|
+
}
|
25
31
|
|
26
|
-
|
32
|
+
SetSerialized();
|
33
|
+
SetPtr(block_id, offset);
|
27
34
|
}
|
28
35
|
|
36
|
+
//===--------------------------------------------------------------------===//
|
37
|
+
// New / Free
|
38
|
+
//===--------------------------------------------------------------------===//
|
39
|
+
|
29
40
|
void Node::New(ART &art, Node &node, const NType type) {
|
30
41
|
|
31
42
|
// NOTE: leaves and prefixes should not pass through this function
|
@@ -50,22 +61,19 @@ void Node::New(ART &art, Node &node, const NType type) {
|
|
50
61
|
|
51
62
|
void Node::Free(ART &art, Node &node) {
|
52
63
|
|
53
|
-
// recursively free all nodes that are in-memory, and skip
|
64
|
+
// recursively free all nodes that are in-memory, and skip serialized and empty nodes
|
54
65
|
if (!node.IsSet()) {
|
55
66
|
return;
|
56
67
|
}
|
57
68
|
|
58
|
-
if (!node.
|
69
|
+
if (!node.IsSerialized()) {
|
59
70
|
|
60
71
|
// free the children of the nodes
|
61
|
-
auto type = node.
|
72
|
+
auto type = node.GetType();
|
62
73
|
switch (type) {
|
63
74
|
case NType::PREFIX:
|
64
75
|
Prefix::Free(art, node);
|
65
76
|
break;
|
66
|
-
case NType::LEAF_SEGMENT:
|
67
|
-
LeafSegment::Free(art, node);
|
68
|
-
break;
|
69
77
|
case NType::LEAF:
|
70
78
|
Leaf::Free(art, node);
|
71
79
|
break;
|
@@ -81,6 +89,9 @@ void Node::Free(ART &art, Node &node) {
|
|
81
89
|
case NType::NODE_256:
|
82
90
|
Node256::Free(art, node);
|
83
91
|
break;
|
92
|
+
case NType::LEAF_INLINED:
|
93
|
+
node.Reset();
|
94
|
+
return;
|
84
95
|
}
|
85
96
|
|
86
97
|
Node::GetAllocator(art, type).Free(node);
|
@@ -96,9 +107,9 @@ void Node::Free(ART &art, Node &node) {
|
|
96
107
|
|
97
108
|
void Node::ReplaceChild(const ART &art, const uint8_t byte, const Node child) {
|
98
109
|
|
99
|
-
D_ASSERT(!
|
110
|
+
D_ASSERT(!IsSerialized());
|
100
111
|
|
101
|
-
switch (
|
112
|
+
switch (GetType()) {
|
102
113
|
case NType::NODE_4:
|
103
114
|
return Node4::Get(art, *this).ReplaceChild(byte, child);
|
104
115
|
case NType::NODE_16:
|
@@ -114,7 +125,7 @@ void Node::ReplaceChild(const ART &art, const uint8_t byte, const Node child) {
|
|
114
125
|
|
115
126
|
void Node::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
116
127
|
|
117
|
-
switch (node.
|
128
|
+
switch (node.GetType()) {
|
118
129
|
case NType::NODE_4:
|
119
130
|
return Node4::InsertChild(art, node, byte, child);
|
120
131
|
case NType::NODE_16:
|
@@ -134,7 +145,7 @@ void Node::InsertChild(ART &art, Node &node, const uint8_t byte, const Node chil
|
|
134
145
|
|
135
146
|
void Node::DeleteChild(ART &art, Node &node, Node &prefix, const uint8_t byte) {
|
136
147
|
|
137
|
-
switch (node.
|
148
|
+
switch (node.GetType()) {
|
138
149
|
case NType::NODE_4:
|
139
150
|
return Node4::DeleteChild(art, node, prefix, byte);
|
140
151
|
case NType::NODE_16:
|
@@ -154,10 +165,10 @@ void Node::DeleteChild(ART &art, Node &node, Node &prefix, const uint8_t byte) {
|
|
154
165
|
|
155
166
|
optional_ptr<Node> Node::GetChild(ART &art, const uint8_t byte) const {
|
156
167
|
|
157
|
-
D_ASSERT(IsSet() && !
|
168
|
+
D_ASSERT(IsSet() && !IsSerialized());
|
158
169
|
|
159
170
|
optional_ptr<Node> child;
|
160
|
-
switch (
|
171
|
+
switch (GetType()) {
|
161
172
|
case NType::NODE_4:
|
162
173
|
child = Node4::Get(art, *this).GetChild(byte);
|
163
174
|
break;
|
@@ -175,7 +186,7 @@ optional_ptr<Node> Node::GetChild(ART &art, const uint8_t byte) const {
|
|
175
186
|
}
|
176
187
|
|
177
188
|
// deserialize the ART node before returning it
|
178
|
-
if (child && child->
|
189
|
+
if (child && child->IsSerialized()) {
|
179
190
|
child->Deserialize(art);
|
180
191
|
}
|
181
192
|
return child;
|
@@ -183,10 +194,10 @@ optional_ptr<Node> Node::GetChild(ART &art, const uint8_t byte) const {
|
|
183
194
|
|
184
195
|
optional_ptr<Node> Node::GetNextChild(ART &art, uint8_t &byte, const bool deserialize) const {
|
185
196
|
|
186
|
-
D_ASSERT(IsSet() && !
|
197
|
+
D_ASSERT(IsSet() && !IsSerialized());
|
187
198
|
|
188
199
|
optional_ptr<Node> child;
|
189
|
-
switch (
|
200
|
+
switch (GetType()) {
|
190
201
|
case NType::NODE_4:
|
191
202
|
child = Node4::Get(art, *this).GetNextChild(byte);
|
192
203
|
break;
|
@@ -204,7 +215,7 @@ optional_ptr<Node> Node::GetNextChild(ART &art, uint8_t &byte, const bool deseri
|
|
204
215
|
}
|
205
216
|
|
206
217
|
// deserialize the ART node before returning it
|
207
|
-
if (child && deserialize && child->
|
218
|
+
if (child && deserialize && child->IsSerialized()) {
|
208
219
|
child->Deserialize(art);
|
209
220
|
}
|
210
221
|
return child;
|
@@ -219,15 +230,15 @@ BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
|
|
219
230
|
if (!IsSet()) {
|
220
231
|
return {(block_id_t)DConstants::INVALID_INDEX, 0};
|
221
232
|
}
|
222
|
-
if (
|
233
|
+
if (IsSerialized()) {
|
223
234
|
Deserialize(art);
|
224
235
|
}
|
225
236
|
|
226
|
-
switch (
|
237
|
+
switch (GetType()) {
|
227
238
|
case NType::PREFIX:
|
228
239
|
return Prefix::Get(art, *this).Serialize(art, writer);
|
229
240
|
case NType::LEAF:
|
230
|
-
return Leaf::
|
241
|
+
return Leaf::Serialize(art, *this, writer);
|
231
242
|
case NType::NODE_4:
|
232
243
|
return Node4::Get(art, *this).Serialize(art, writer);
|
233
244
|
case NType::NODE_16:
|
@@ -236,27 +247,35 @@ BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
|
|
236
247
|
return Node48::Get(art, *this).Serialize(art, writer);
|
237
248
|
case NType::NODE_256:
|
238
249
|
return Node256::Get(art, *this).Serialize(art, writer);
|
239
|
-
|
240
|
-
|
250
|
+
case NType::LEAF_INLINED:
|
251
|
+
return Leaf::Serialize(art, *this, writer);
|
241
252
|
}
|
253
|
+
throw InternalException("Invalid node type for Serialize.");
|
242
254
|
}
|
243
255
|
|
244
256
|
void Node::Deserialize(ART &art) {
|
245
257
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
258
|
+
D_ASSERT(IsSet() && IsSerialized());
|
259
|
+
|
260
|
+
MetaBlockReader reader(art.table_io_manager.GetIndexBlockManager(), GetBufferId());
|
261
|
+
reader.offset = GetOffset();
|
262
|
+
Reset();
|
263
|
+
SetType(reader.Read<uint8_t>());
|
264
|
+
|
265
|
+
auto decoded_type = GetType();
|
266
|
+
if (decoded_type == NType::LEAF_INLINED) {
|
267
|
+
SetRowId(reader.Read<row_t>());
|
268
|
+
return;
|
269
|
+
}
|
250
270
|
|
251
|
-
|
252
|
-
|
253
|
-
type = (uint8_t)decoded_type;
|
271
|
+
*this = Node::GetAllocator(art, decoded_type).New();
|
272
|
+
SetType((uint8_t)decoded_type);
|
254
273
|
|
255
274
|
switch (decoded_type) {
|
256
275
|
case NType::PREFIX:
|
257
276
|
return Prefix::Get(art, *this).Deserialize(reader);
|
258
277
|
case NType::LEAF:
|
259
|
-
return Leaf::
|
278
|
+
return Leaf::Deserialize(art, *this, reader);
|
260
279
|
case NType::NODE_4:
|
261
280
|
return Node4::Get(art, *this).Deserialize(reader);
|
262
281
|
case NType::NODE_16:
|
@@ -277,32 +296,27 @@ void Node::Deserialize(ART &art) {
|
|
277
296
|
string Node::VerifyAndToString(ART &art, const bool only_verify) {
|
278
297
|
|
279
298
|
D_ASSERT(IsSet());
|
280
|
-
if (
|
281
|
-
return only_verify ? "" : "
|
299
|
+
if (IsSerialized()) {
|
300
|
+
return only_verify ? "" : "serialized";
|
282
301
|
}
|
283
302
|
|
284
|
-
|
285
|
-
|
286
|
-
auto str = Leaf::Get(art, *this).VerifyAndToString(art, only_verify);
|
303
|
+
if (GetType() == NType::LEAF || GetType() == NType::LEAF_INLINED) {
|
304
|
+
auto str = Leaf::VerifyAndToString(art, *this);
|
287
305
|
return only_verify ? "" : "\n" + str;
|
288
306
|
}
|
289
|
-
if (
|
290
|
-
auto str = Prefix::Get(art, *this).VerifyAndToString(art, only_verify);
|
307
|
+
if (GetType() == NType::PREFIX) {
|
308
|
+
auto str = Prefix::Get(art, *this).VerifyAndToString(art, *this, only_verify);
|
291
309
|
return only_verify ? "" : "\n" + str;
|
292
310
|
}
|
293
311
|
|
294
312
|
string str = "Node" + to_string(GetCapacity()) + ": [";
|
295
|
-
|
296
|
-
idx_t child_count = 0;
|
297
313
|
uint8_t byte = 0;
|
298
314
|
auto child = GetNextChild(art, byte, false);
|
299
315
|
|
300
316
|
while (child) {
|
301
|
-
|
302
|
-
child_count++;
|
303
|
-
if (child->IsSwizzled()) {
|
317
|
+
if (child->IsSerialized()) {
|
304
318
|
if (!only_verify) {
|
305
|
-
str += "(
|
319
|
+
str += "(serialized)";
|
306
320
|
}
|
307
321
|
} else {
|
308
322
|
str += "(" + to_string(byte) + ", " + child->VerifyAndToString(art, only_verify) + ")";
|
@@ -315,17 +329,14 @@ string Node::VerifyAndToString(ART &art, const bool only_verify) {
|
|
315
329
|
child = GetNextChild(art, byte, false);
|
316
330
|
}
|
317
331
|
|
318
|
-
(void)child_count;
|
319
|
-
// ensure that the child count is at least two
|
320
|
-
D_ASSERT(child_count > 1);
|
321
332
|
return only_verify ? "" : "\n" + str + "]";
|
322
333
|
}
|
323
334
|
|
324
335
|
idx_t Node::GetCapacity() const {
|
325
336
|
|
326
|
-
D_ASSERT(!
|
337
|
+
D_ASSERT(!IsSerialized());
|
327
338
|
|
328
|
-
switch (
|
339
|
+
switch (GetType()) {
|
329
340
|
case NType::NODE_4:
|
330
341
|
return Node::NODE_4_CAPACITY;
|
331
342
|
case NType::NODE_16:
|
@@ -362,19 +373,14 @@ FixedSizeAllocator &Node::GetAllocator(const ART &art, NType type) {
|
|
362
373
|
void Node::InitializeMerge(ART &art, const ARTFlags &flags) {
|
363
374
|
|
364
375
|
// the index is fully in memory during CREATE [UNIQUE] INDEX statements
|
365
|
-
D_ASSERT(IsSet() && !
|
376
|
+
D_ASSERT(IsSet() && !IsSerialized());
|
366
377
|
|
367
|
-
|
368
|
-
switch (type) {
|
378
|
+
switch (GetType()) {
|
369
379
|
case NType::PREFIX:
|
370
380
|
Prefix::Get(art, *this).InitializeMerge(art, flags);
|
371
381
|
break;
|
372
382
|
case NType::LEAF:
|
373
|
-
|
374
|
-
if (flags.merge_buffer_counts[(uint8_t)NType::LEAF_SEGMENT - 1] != 0) {
|
375
|
-
// initialize leaf segments
|
376
|
-
Leaf::Get(art, *this).InitializeMerge(art, flags.merge_buffer_counts[(uint8_t)NType::LEAF_SEGMENT - 1]);
|
377
|
-
}
|
383
|
+
Leaf::InitializeMerge(art, *this, flags);
|
378
384
|
break;
|
379
385
|
case NType::NODE_4:
|
380
386
|
Node4::Get(art, *this).InitializeMerge(art, flags);
|
@@ -388,11 +394,12 @@ void Node::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
388
394
|
case NType::NODE_256:
|
389
395
|
Node256::Get(art, *this).InitializeMerge(art, flags);
|
390
396
|
break;
|
391
|
-
|
392
|
-
|
397
|
+
case NType::LEAF_INLINED:
|
398
|
+
return;
|
393
399
|
}
|
394
400
|
|
395
|
-
|
401
|
+
// NOTE: this works because the rightmost 32 bits contain the buffer ID
|
402
|
+
data += flags.merge_buffer_counts[(uint8_t)GetType() - 1];
|
396
403
|
}
|
397
404
|
|
398
405
|
bool Node::Merge(ART &art, Node &other) {
|
@@ -412,7 +419,7 @@ bool MergePrefixContainsOtherPrefix(ART &art, reference<Node> &l_node, reference
|
|
412
419
|
// r_node's prefix contains l_node's prefix
|
413
420
|
// l_node cannot be a leaf, otherwise the key represented by l_node would be a subset of another key
|
414
421
|
// which is not possible by our construction
|
415
|
-
D_ASSERT(l_node.get().
|
422
|
+
D_ASSERT(l_node.get().GetType() != NType::LEAF && l_node.get().GetType() != NType::LEAF_INLINED);
|
416
423
|
|
417
424
|
// test if the next byte (mismatch_position) in r_node (prefix) exists in l_node
|
418
425
|
auto mismatch_byte = Prefix::GetByte(art, r_node, mismatch_position);
|
@@ -454,11 +461,10 @@ bool Node::ResolvePrefixes(ART &art, Node &other) {
|
|
454
461
|
|
455
462
|
// NOTE: we always merge into the left ART
|
456
463
|
|
457
|
-
D_ASSERT(IsSet());
|
458
|
-
D_ASSERT(other.IsSet());
|
464
|
+
D_ASSERT(IsSet() && other.IsSet());
|
459
465
|
|
460
466
|
// case 1: both nodes have no prefix
|
461
|
-
if (
|
467
|
+
if (GetType() != NType::PREFIX && other.GetType() != NType::PREFIX) {
|
462
468
|
return MergeInternal(art, other);
|
463
469
|
}
|
464
470
|
|
@@ -468,7 +474,7 @@ bool Node::ResolvePrefixes(ART &art, Node &other) {
|
|
468
474
|
idx_t mismatch_position = DConstants::INVALID_INDEX;
|
469
475
|
|
470
476
|
// traverse prefixes
|
471
|
-
if (l_node.get().
|
477
|
+
if (l_node.get().GetType() == NType::PREFIX && r_node.get().GetType() == NType::PREFIX) {
|
472
478
|
|
473
479
|
if (!Prefix::Traverse(art, l_node, r_node, mismatch_position)) {
|
474
480
|
return false;
|
@@ -481,7 +487,7 @@ bool Node::ResolvePrefixes(ART &art, Node &other) {
|
|
481
487
|
} else {
|
482
488
|
|
483
489
|
// l_prefix contains r_prefix
|
484
|
-
if (l_node.get().
|
490
|
+
if (l_node.get().GetType() == NType::PREFIX) {
|
485
491
|
swap(*this, other);
|
486
492
|
}
|
487
493
|
mismatch_position = 0;
|
@@ -489,7 +495,7 @@ bool Node::ResolvePrefixes(ART &art, Node &other) {
|
|
489
495
|
D_ASSERT(mismatch_position != DConstants::INVALID_INDEX);
|
490
496
|
|
491
497
|
// case 2: one prefix contains the other prefix
|
492
|
-
if (l_node.get().
|
498
|
+
if (l_node.get().GetType() != NType::PREFIX && r_node.get().GetType() == NType::PREFIX) {
|
493
499
|
return MergePrefixContainsOtherPrefix(art, l_node, r_node, mismatch_position);
|
494
500
|
}
|
495
501
|
|
@@ -501,13 +507,12 @@ bool Node::ResolvePrefixes(ART &art, Node &other) {
|
|
501
507
|
bool Node::MergeInternal(ART &art, Node &other) {
|
502
508
|
|
503
509
|
D_ASSERT(IsSet() && other.IsSet());
|
504
|
-
D_ASSERT(
|
505
|
-
D_ASSERT(other.DecodeARTNodeType() != NType::PREFIX && other.DecodeARTNodeType() != NType::LEAF_SEGMENT);
|
510
|
+
D_ASSERT(GetType() != NType::PREFIX && other.GetType() != NType::PREFIX);
|
506
511
|
|
507
512
|
// always try to merge the smaller node into the bigger node
|
508
513
|
// because maybe there is enough free space in the bigger node to fit the smaller one
|
509
514
|
// without too much recursion
|
510
|
-
if (
|
515
|
+
if (GetType() < other.GetType()) {
|
511
516
|
swap(*this, other);
|
512
517
|
}
|
513
518
|
|
@@ -515,14 +520,14 @@ bool Node::MergeInternal(ART &art, Node &other) {
|
|
515
520
|
auto &l_node = *this;
|
516
521
|
auto &r_node = other;
|
517
522
|
|
518
|
-
if (r_node.
|
519
|
-
D_ASSERT(l_node.
|
523
|
+
if (r_node.GetType() == NType::LEAF || r_node.GetType() == NType::LEAF_INLINED) {
|
524
|
+
D_ASSERT(l_node.GetType() == NType::LEAF || l_node.GetType() == NType::LEAF_INLINED);
|
520
525
|
|
521
526
|
if (art.IsUnique()) {
|
522
527
|
return false;
|
523
528
|
}
|
524
529
|
|
525
|
-
Leaf::
|
530
|
+
Leaf::Merge(art, l_node, r_node);
|
526
531
|
return true;
|
527
532
|
}
|
528
533
|
|
@@ -559,38 +564,42 @@ bool Node::MergeInternal(ART &art, Node &other) {
|
|
559
564
|
// Vacuum
|
560
565
|
//===--------------------------------------------------------------------===//
|
561
566
|
|
562
|
-
void Node::Vacuum(ART &art,
|
567
|
+
void Node::Vacuum(ART &art, const ARTFlags &flags) {
|
563
568
|
|
564
|
-
|
569
|
+
D_ASSERT(IsSet());
|
570
|
+
if (IsSerialized()) {
|
565
571
|
return;
|
566
572
|
}
|
567
573
|
|
568
|
-
auto
|
569
|
-
|
570
|
-
|
571
|
-
if (needs_vacuum) {
|
572
|
-
node.SetPtr(allocator.VacuumPointer(node));
|
573
|
-
node.type = (uint8_t)type;
|
574
|
+
auto node_type = GetType();
|
575
|
+
if (node_type == NType::LEAF_INLINED) {
|
576
|
+
return;
|
574
577
|
}
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
return Prefix::Get(art, node).Vacuum(art, flags);
|
579
|
-
case NType::LEAF: {
|
580
|
-
// possibly vacuum leaf segments, if not all leaves are inlined
|
581
|
-
if (flags.vacuum_flags[(uint8_t)NType::LEAF_SEGMENT - 1]) {
|
582
|
-
Leaf::Get(art, node).Vacuum(art);
|
578
|
+
if (node_type == NType::LEAF) {
|
579
|
+
if (flags.vacuum_flags[(uint8_t)GetType() - 1]) {
|
580
|
+
Leaf::Vacuum(art, *this);
|
583
581
|
}
|
584
582
|
return;
|
585
583
|
}
|
584
|
+
|
585
|
+
auto &allocator = Node::GetAllocator(art, node_type);
|
586
|
+
auto needs_vacuum = flags.vacuum_flags[(uint8_t)GetType() - 1] && allocator.NeedsVacuum(*this);
|
587
|
+
if (needs_vacuum) {
|
588
|
+
*this = allocator.VacuumPointer(*this);
|
589
|
+
SetType((uint8_t)node_type);
|
590
|
+
}
|
591
|
+
|
592
|
+
switch (node_type) {
|
593
|
+
case NType::PREFIX:
|
594
|
+
return Prefix::Get(art, *this).Vacuum(art, flags);
|
586
595
|
case NType::NODE_4:
|
587
|
-
return Node4::Get(art,
|
596
|
+
return Node4::Get(art, *this).Vacuum(art, flags);
|
588
597
|
case NType::NODE_16:
|
589
|
-
return Node16::Get(art,
|
598
|
+
return Node16::Get(art, *this).Vacuum(art, flags);
|
590
599
|
case NType::NODE_48:
|
591
|
-
return Node48::Get(art,
|
600
|
+
return Node48::Get(art, *this).Vacuum(art, flags);
|
592
601
|
case NType::NODE_256:
|
593
|
-
return Node256::Get(art,
|
602
|
+
return Node256::Get(art, *this).Vacuum(art, flags);
|
594
603
|
default:
|
595
604
|
throw InternalException("Invalid node type for Vacuum.");
|
596
605
|
}
|
@@ -9,8 +9,8 @@ namespace duckdb {
|
|
9
9
|
|
10
10
|
Node16 &Node16::New(ART &art, Node &node) {
|
11
11
|
|
12
|
-
node
|
13
|
-
node.
|
12
|
+
node = Node::GetAllocator(art, NType::NODE_16).New();
|
13
|
+
node.SetType((uint8_t)NType::NODE_16);
|
14
14
|
auto &n16 = Node16::Get(art, node);
|
15
15
|
|
16
16
|
n16.count = 0;
|
@@ -20,7 +20,7 @@ Node16 &Node16::New(ART &art, Node &node) {
|
|
20
20
|
void Node16::Free(ART &art, Node &node) {
|
21
21
|
|
22
22
|
D_ASSERT(node.IsSet());
|
23
|
-
D_ASSERT(!node.
|
23
|
+
D_ASSERT(!node.IsSerialized());
|
24
24
|
|
25
25
|
auto &n16 = Node16::Get(art, node);
|
26
26
|
|
@@ -76,7 +76,7 @@ void Node16::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
76
76
|
void Node16::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
77
77
|
|
78
78
|
D_ASSERT(node.IsSet());
|
79
|
-
D_ASSERT(!node.
|
79
|
+
D_ASSERT(!node.IsSerialized());
|
80
80
|
auto &n16 = Node16::Get(art, node);
|
81
81
|
|
82
82
|
// ensure that there is no other child at the same byte
|
@@ -112,7 +112,7 @@ void Node16::InsertChild(ART &art, Node &node, const uint8_t byte, const Node ch
|
|
112
112
|
void Node16::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
113
113
|
|
114
114
|
D_ASSERT(node.IsSet());
|
115
|
-
D_ASSERT(!node.
|
115
|
+
D_ASSERT(!node.IsSerialized());
|
116
116
|
auto &n16 = Node16::Get(art, node);
|
117
117
|
|
118
118
|
idx_t child_pos = 0;
|
@@ -221,7 +221,7 @@ void Node16::Deserialize(MetaBlockReader &reader) {
|
|
221
221
|
void Node16::Vacuum(ART &art, const ARTFlags &flags) {
|
222
222
|
|
223
223
|
for (idx_t i = 0; i < count; i++) {
|
224
|
-
|
224
|
+
children[i].Vacuum(art, flags);
|
225
225
|
}
|
226
226
|
}
|
227
227
|
|
@@ -8,8 +8,8 @@ namespace duckdb {
|
|
8
8
|
|
9
9
|
Node256 &Node256::New(ART &art, Node &node) {
|
10
10
|
|
11
|
-
node
|
12
|
-
node.
|
11
|
+
node = Node::GetAllocator(art, NType::NODE_256).New();
|
12
|
+
node.SetType((uint8_t)NType::NODE_256);
|
13
13
|
auto &n256 = Node256::Get(art, node);
|
14
14
|
|
15
15
|
n256.count = 0;
|
@@ -23,7 +23,7 @@ Node256 &Node256::New(ART &art, Node &node) {
|
|
23
23
|
void Node256::Free(ART &art, Node &node) {
|
24
24
|
|
25
25
|
D_ASSERT(node.IsSet());
|
26
|
-
D_ASSERT(!node.
|
26
|
+
D_ASSERT(!node.IsSerialized());
|
27
27
|
|
28
28
|
auto &n256 = Node256::Get(art, node);
|
29
29
|
|
@@ -70,7 +70,7 @@ void Node256::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
70
70
|
void Node256::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
71
71
|
|
72
72
|
D_ASSERT(node.IsSet());
|
73
|
-
D_ASSERT(!node.
|
73
|
+
D_ASSERT(!node.IsSerialized());
|
74
74
|
auto &n256 = Node256::Get(art, node);
|
75
75
|
|
76
76
|
// ensure that there is no other child at the same byte
|
@@ -84,7 +84,7 @@ void Node256::InsertChild(ART &art, Node &node, const uint8_t byte, const Node c
|
|
84
84
|
void Node256::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
85
85
|
|
86
86
|
D_ASSERT(node.IsSet());
|
87
|
-
D_ASSERT(!node.
|
87
|
+
D_ASSERT(!node.IsSerialized());
|
88
88
|
auto &n256 = Node256::Get(art, node);
|
89
89
|
|
90
90
|
// free the child and decrease the count
|
@@ -145,7 +145,7 @@ void Node256::Vacuum(ART &art, const ARTFlags &flags) {
|
|
145
145
|
|
146
146
|
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
147
147
|
if (children[i].IsSet()) {
|
148
|
-
|
148
|
+
children[i].Vacuum(art, flags);
|
149
149
|
}
|
150
150
|
}
|
151
151
|
}
|
@@ -9,8 +9,8 @@ namespace duckdb {
|
|
9
9
|
|
10
10
|
Node4 &Node4::New(ART &art, Node &node) {
|
11
11
|
|
12
|
-
node
|
13
|
-
node.
|
12
|
+
node = Node::GetAllocator(art, NType::NODE_4).New();
|
13
|
+
node.SetType((uint8_t)NType::NODE_4);
|
14
14
|
auto &n4 = Node4::Get(art, node);
|
15
15
|
|
16
16
|
n4.count = 0;
|
@@ -20,7 +20,7 @@ Node4 &Node4::New(ART &art, Node &node) {
|
|
20
20
|
void Node4::Free(ART &art, Node &node) {
|
21
21
|
|
22
22
|
D_ASSERT(node.IsSet());
|
23
|
-
D_ASSERT(!node.
|
23
|
+
D_ASSERT(!node.IsSerialized());
|
24
24
|
|
25
25
|
auto &n4 = Node4::Get(art, node);
|
26
26
|
|
@@ -57,7 +57,7 @@ void Node4::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
57
57
|
void Node4::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
58
58
|
|
59
59
|
D_ASSERT(node.IsSet());
|
60
|
-
D_ASSERT(!node.
|
60
|
+
D_ASSERT(!node.IsSerialized());
|
61
61
|
auto &n4 = Node4::Get(art, node);
|
62
62
|
|
63
63
|
// ensure that there is no other child at the same byte
|
@@ -93,7 +93,7 @@ void Node4::InsertChild(ART &art, Node &node, const uint8_t byte, const Node chi
|
|
93
93
|
void Node4::DeleteChild(ART &art, Node &node, Node &prefix, const uint8_t byte) {
|
94
94
|
|
95
95
|
D_ASSERT(node.IsSet());
|
96
|
-
D_ASSERT(!node.
|
96
|
+
D_ASSERT(!node.IsSerialized());
|
97
97
|
auto &n4 = Node4::Get(art, node);
|
98
98
|
|
99
99
|
idx_t child_pos = 0;
|
@@ -214,7 +214,7 @@ void Node4::Deserialize(MetaBlockReader &reader) {
|
|
214
214
|
void Node4::Vacuum(ART &art, const ARTFlags &flags) {
|
215
215
|
|
216
216
|
for (idx_t i = 0; i < count; i++) {
|
217
|
-
|
217
|
+
children[i].Vacuum(art, flags);
|
218
218
|
}
|
219
219
|
}
|
220
220
|
|
@@ -9,8 +9,8 @@ namespace duckdb {
|
|
9
9
|
|
10
10
|
Node48 &Node48::New(ART &art, Node &node) {
|
11
11
|
|
12
|
-
node
|
13
|
-
node.
|
12
|
+
node = Node::GetAllocator(art, NType::NODE_48).New();
|
13
|
+
node.SetType((uint8_t)NType::NODE_48);
|
14
14
|
auto &n48 = Node48::Get(art, node);
|
15
15
|
|
16
16
|
n48.count = 0;
|
@@ -29,7 +29,7 @@ Node48 &Node48::New(ART &art, Node &node) {
|
|
29
29
|
void Node48::Free(ART &art, Node &node) {
|
30
30
|
|
31
31
|
D_ASSERT(node.IsSet());
|
32
|
-
D_ASSERT(!node.
|
32
|
+
D_ASSERT(!node.IsSerialized());
|
33
33
|
|
34
34
|
auto &n48 = Node48::Get(art, node);
|
35
35
|
|
@@ -109,7 +109,7 @@ void Node48::InitializeMerge(ART &art, const ARTFlags &flags) {
|
|
109
109
|
void Node48::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
110
110
|
|
111
111
|
D_ASSERT(node.IsSet());
|
112
|
-
D_ASSERT(!node.
|
112
|
+
D_ASSERT(!node.IsSerialized());
|
113
113
|
auto &n48 = Node48::Get(art, node);
|
114
114
|
|
115
115
|
// ensure that there is no other child at the same byte
|
@@ -141,7 +141,7 @@ void Node48::InsertChild(ART &art, Node &node, const uint8_t byte, const Node ch
|
|
141
141
|
void Node48::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
142
142
|
|
143
143
|
D_ASSERT(node.IsSet());
|
144
|
-
D_ASSERT(!node.
|
144
|
+
D_ASSERT(!node.IsSerialized());
|
145
145
|
auto &n48 = Node48::Get(art, node);
|
146
146
|
|
147
147
|
// free the child and decrease the count
|
@@ -214,7 +214,7 @@ void Node48::Vacuum(ART &art, const ARTFlags &flags) {
|
|
214
214
|
|
215
215
|
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
216
216
|
if (child_index[i] != Node::EMPTY_MARKER) {
|
217
|
-
|
217
|
+
children[child_index[i]].Vacuum(art, flags);
|
218
218
|
}
|
219
219
|
}
|
220
220
|
}
|