duckdb 0.7.2-dev2552.0 → 0.7.2-dev2675.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 +7 -7
- package/package.json +2 -2
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +3 -0
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +2 -2
- package/src/duckdb/src/common/radix_partitioning.cpp +1 -1
- package/src/duckdb/src/execution/index/art/art.cpp +286 -269
- package/src/duckdb/src/execution/index/art/art_key.cpp +22 -32
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +224 -0
- package/src/duckdb/src/execution/index/art/iterator.cpp +142 -123
- package/src/duckdb/src/execution/index/art/leaf.cpp +319 -170
- package/src/duckdb/src/execution/index/art/leaf_segment.cpp +42 -0
- package/src/duckdb/src/execution/index/art/node.cpp +444 -379
- package/src/duckdb/src/execution/index/art/node16.cpp +178 -114
- package/src/duckdb/src/execution/index/art/node256.cpp +117 -79
- package/src/duckdb/src/execution/index/art/node4.cpp +169 -114
- package/src/duckdb/src/execution/index/art/node48.cpp +175 -105
- package/src/duckdb/src/execution/index/art/prefix.cpp +405 -127
- package/src/duckdb/src/execution/index/art/prefix_segment.cpp +42 -0
- package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +10 -85
- package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +2 -1
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +2 -2
- package/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp +2 -0
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +11 -12
- package/src/duckdb/src/function/table/read_csv.cpp +5 -1
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/queue.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +53 -45
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +29 -24
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +114 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +26 -20
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +63 -39
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +36 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +98 -116
- package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +48 -36
- package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +52 -35
- package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +46 -36
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +57 -35
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +57 -50
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix_segment.hpp +40 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +38 -31
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_file_handle.hpp +2 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/statement/insert_statement.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +0 -5
- package/src/duckdb/src/include/duckdb/storage/index.hpp +13 -28
- package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +0 -2
- package/src/duckdb/src/include/duckdb/transaction/cleanup_state.hpp +5 -0
- package/src/duckdb/src/include/duckdb.h +26 -0
- package/src/duckdb/src/main/capi/helper-c.cpp +7 -0
- package/src/duckdb/src/parser/statement/insert_statement.cpp +15 -6
- package/src/duckdb/src/parser/transform/constraint/transform_constraint.cpp +1 -1
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +18 -5
- package/src/duckdb/src/parser/transform/statement/transform_insert.cpp +5 -7
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +20 -7
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +14 -9
- package/src/duckdb/src/storage/checkpoint_manager.cpp +11 -9
- package/src/duckdb/src/storage/data_table.cpp +6 -3
- package/src/duckdb/src/storage/index.cpp +18 -6
- package/src/duckdb/src/storage/local_storage.cpp +8 -2
- package/src/duckdb/src/storage/standard_buffer_manager.cpp +0 -9
- package/src/duckdb/src/storage/wal_replay.cpp +1 -1
- package/src/duckdb/src/transaction/cleanup_state.cpp +6 -0
- package/src/duckdb/src/transaction/undo_buffer.cpp +8 -0
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_execution_index_art.cpp +7 -1
@@ -1,528 +1,593 @@
|
|
1
|
-
#include "duckdb/
|
2
|
-
|
3
|
-
#include "duckdb/common/exception.hpp"
|
1
|
+
#include "duckdb/common/limits.hpp"
|
4
2
|
#include "duckdb/common/swap.hpp"
|
5
3
|
#include "duckdb/execution/index/art/art.hpp"
|
6
|
-
#include "duckdb/execution/index/art/
|
7
|
-
#include "duckdb/
|
4
|
+
#include "duckdb/execution/index/art/leaf.hpp"
|
5
|
+
#include "duckdb/execution/index/art/leaf_segment.hpp"
|
6
|
+
#include "duckdb/execution/index/art/node.hpp"
|
7
|
+
#include "duckdb/execution/index/art/node16.hpp"
|
8
|
+
#include "duckdb/execution/index/art/node256.hpp"
|
9
|
+
#include "duckdb/execution/index/art/node4.hpp"
|
10
|
+
#include "duckdb/execution/index/art/node48.hpp"
|
11
|
+
#include "duckdb/execution/index/art/prefix.hpp"
|
12
|
+
#include "duckdb/execution/index/art/prefix_segment.hpp"
|
13
|
+
#include "duckdb/storage/meta_block_reader.hpp"
|
14
|
+
#include "duckdb/storage/meta_block_writer.hpp"
|
15
|
+
#include "duckdb/storage/table_io_manager.hpp"
|
8
16
|
|
9
17
|
namespace duckdb {
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
auto n4 = (Node4 *)n;
|
15
|
-
Set(n4->key, 4, n4->children, 4);
|
16
|
-
break;
|
17
|
-
}
|
18
|
-
case NodeType::N16: {
|
19
|
-
auto n16 = (Node16 *)n;
|
20
|
-
Set(n16->key, 16, n16->children, 16);
|
21
|
-
break;
|
22
|
-
}
|
23
|
-
case NodeType::N48: {
|
24
|
-
auto n48 = (Node48 *)n;
|
25
|
-
Set(n48->child_index, 256, n48->children, 48);
|
26
|
-
break;
|
27
|
-
}
|
28
|
-
case NodeType::N256: {
|
29
|
-
auto n256 = (Node256 *)n;
|
30
|
-
Set(nullptr, 0, n256->children, 256);
|
31
|
-
break;
|
32
|
-
}
|
33
|
-
default:
|
34
|
-
throw InternalException("This is not an Internal ART Node Type");
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
void InternalType::Set(uint8_t *key_p, uint16_t key_size_p, ARTPointer *children_p, uint16_t children_size_p) {
|
39
|
-
key = key_p;
|
40
|
-
key_size = key_size_p;
|
41
|
-
children = children_p;
|
42
|
-
children_size = children_size_p;
|
43
|
-
}
|
44
|
-
|
45
|
-
Node::Node(NodeType type) : count(0), type(type) {
|
46
|
-
}
|
47
|
-
|
48
|
-
// LCOV_EXCL_START
|
49
|
-
idx_t Node::MemorySize(ART &, const bool &) {
|
50
|
-
throw InternalException("MemorySize not implemented for the specific node type.");
|
51
|
-
}
|
52
|
-
|
53
|
-
idx_t Node::GetMin() {
|
54
|
-
throw InternalException("GetMin not implemented for the specific node type.");
|
55
|
-
}
|
19
|
+
//===--------------------------------------------------------------------===//
|
20
|
+
// Constructors / Destructors
|
21
|
+
//===--------------------------------------------------------------------===//
|
56
22
|
|
57
|
-
Node
|
58
|
-
throw InternalException("GetChild not implemented for the specific node type.");
|
23
|
+
Node::Node() : SwizzleablePointer() {
|
59
24
|
}
|
60
25
|
|
61
|
-
|
62
|
-
throw InternalException("ReplaceChildPointer not implemented for the specific node type.");
|
26
|
+
Node::Node(MetaBlockReader &reader) : SwizzleablePointer(reader) {
|
63
27
|
}
|
64
28
|
|
65
|
-
|
66
|
-
throw InternalException("ChildIsInMemory not implemented for the specific node type.");
|
67
|
-
}
|
68
|
-
// LCOV_EXCL_STOP
|
29
|
+
void Node::New(ART &art, Node &node, const NType type) {
|
69
30
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
Node4::InsertChild(art, node, key_byte, new_child);
|
74
|
-
break;
|
75
|
-
case NodeType::N16:
|
76
|
-
Node16::InsertChild(art, node, key_byte, new_child);
|
77
|
-
break;
|
78
|
-
case NodeType::N48:
|
79
|
-
Node48::InsertChild(art, node, key_byte, new_child);
|
31
|
+
switch (type) {
|
32
|
+
case NType::PREFIX_SEGMENT:
|
33
|
+
PrefixSegment::New(art, node);
|
80
34
|
break;
|
81
|
-
case
|
82
|
-
|
35
|
+
case NType::LEAF_SEGMENT:
|
36
|
+
LeafSegment::New(art, node);
|
83
37
|
break;
|
84
|
-
|
85
|
-
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
void Node::EraseChild(ART &art, Node *&node, idx_t pos) {
|
90
|
-
switch (node->type) {
|
91
|
-
case NodeType::N4: {
|
92
|
-
Node4::EraseChild(art, node, pos);
|
38
|
+
case NType::NODE_4:
|
39
|
+
Node4::New(art, node);
|
93
40
|
break;
|
94
|
-
|
95
|
-
|
96
|
-
Node16::EraseChild(art, node, pos);
|
41
|
+
case NType::NODE_16:
|
42
|
+
Node16::New(art, node);
|
97
43
|
break;
|
98
|
-
|
99
|
-
|
100
|
-
Node48::EraseChild(art, node, pos);
|
44
|
+
case NType::NODE_48:
|
45
|
+
Node48::New(art, node);
|
101
46
|
break;
|
102
|
-
|
103
|
-
|
104
|
-
Node256::EraseChild(art, node, pos);
|
47
|
+
case NType::NODE_256:
|
48
|
+
Node256::New(art, node);
|
105
49
|
break;
|
106
50
|
default:
|
107
|
-
throw InternalException("
|
51
|
+
throw InternalException("Invalid node type for New.");
|
108
52
|
}
|
109
53
|
}
|
110
54
|
|
111
|
-
|
55
|
+
void Node::Free(ART &art, Node &node) {
|
112
56
|
|
113
|
-
|
114
|
-
return NodeType::N4;
|
115
|
-
} else if (size <= Node16::GetSize()) {
|
116
|
-
return NodeType::N16;
|
117
|
-
} else if (size <= Node48::GetSize()) {
|
118
|
-
return NodeType::N48;
|
119
|
-
}
|
120
|
-
D_ASSERT(size <= Node256::GetSize());
|
121
|
-
return NodeType::N256;
|
122
|
-
}
|
57
|
+
// recursively free all nodes that are in-memory, and skip swizzled and empty nodes
|
123
58
|
|
124
|
-
|
125
|
-
switch (type) {
|
126
|
-
case NodeType::N4:
|
127
|
-
node = (Node *)Node4::New();
|
59
|
+
if (!node.IsSet()) {
|
128
60
|
return;
|
129
|
-
case NodeType::N16:
|
130
|
-
node = (Node *)Node16::New();
|
131
|
-
return;
|
132
|
-
case NodeType::N48:
|
133
|
-
node = (Node *)Node48::New();
|
134
|
-
return;
|
135
|
-
case NodeType::N256:
|
136
|
-
node = (Node *)Node256::New();
|
137
|
-
return;
|
138
|
-
default:
|
139
|
-
throw InternalException("Unrecognized node type for new node creation.");
|
140
61
|
}
|
141
|
-
}
|
142
62
|
|
143
|
-
|
144
|
-
return AllocateObject<Node4>();
|
145
|
-
}
|
63
|
+
if (!node.IsSwizzled()) {
|
146
64
|
|
147
|
-
|
148
|
-
|
149
|
-
|
65
|
+
auto type = node.DecodeARTNodeType();
|
66
|
+
if (type != NType::PREFIX_SEGMENT && type != NType::LEAF_SEGMENT) {
|
67
|
+
node.GetPrefix(art).Free(art);
|
68
|
+
}
|
150
69
|
|
151
|
-
|
152
|
-
|
153
|
-
|
70
|
+
// free the prefixes and children of the nodes
|
71
|
+
switch (type) {
|
72
|
+
case NType::LEAF:
|
73
|
+
Leaf::Free(art, node);
|
74
|
+
break;
|
75
|
+
case NType::NODE_4:
|
76
|
+
Node4::Free(art, node);
|
77
|
+
break;
|
78
|
+
case NType::NODE_16:
|
79
|
+
Node16::Free(art, node);
|
80
|
+
break;
|
81
|
+
case NType::NODE_48:
|
82
|
+
Node48::Free(art, node);
|
83
|
+
break;
|
84
|
+
case NType::NODE_256:
|
85
|
+
Node256::Free(art, node);
|
86
|
+
break;
|
87
|
+
default:
|
88
|
+
break;
|
89
|
+
}
|
154
90
|
|
155
|
-
|
156
|
-
|
157
|
-
}
|
91
|
+
Node::GetAllocator(art, type).Free(node);
|
92
|
+
}
|
158
93
|
|
159
|
-
|
160
|
-
|
94
|
+
// overwrite with an empty ART node
|
95
|
+
node.Reset();
|
161
96
|
}
|
162
97
|
|
163
|
-
|
164
|
-
|
165
|
-
|
98
|
+
//===--------------------------------------------------------------------===//
|
99
|
+
// Inserts
|
100
|
+
//===--------------------------------------------------------------------===//
|
101
|
+
|
102
|
+
void Node::ReplaceChild(const ART &art, const uint8_t byte, const Node child) {
|
166
103
|
|
167
|
-
|
168
|
-
|
104
|
+
D_ASSERT(!IsSwizzled());
|
105
|
+
|
106
|
+
switch (DecodeARTNodeType()) {
|
107
|
+
case NType::NODE_4:
|
108
|
+
return Node4::Get(art, *this).ReplaceChild(byte, child);
|
109
|
+
case NType::NODE_16:
|
110
|
+
return Node16::Get(art, *this).ReplaceChild(byte, child);
|
111
|
+
case NType::NODE_48:
|
112
|
+
return Node48::Get(art, *this).ReplaceChild(byte, child);
|
113
|
+
case NType::NODE_256:
|
114
|
+
return Node256::Get(art, *this).ReplaceChild(byte, child);
|
115
|
+
default:
|
116
|
+
throw InternalException("Invalid node type for ReplaceChild.");
|
117
|
+
}
|
169
118
|
}
|
170
119
|
|
171
|
-
|
172
|
-
|
120
|
+
void Node::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
121
|
+
|
122
|
+
switch (node.DecodeARTNodeType()) {
|
123
|
+
case NType::NODE_4:
|
124
|
+
return Node4::InsertChild(art, node, byte, child);
|
125
|
+
case NType::NODE_16:
|
126
|
+
return Node16::InsertChild(art, node, byte, child);
|
127
|
+
case NType::NODE_48:
|
128
|
+
return Node48::InsertChild(art, node, byte, child);
|
129
|
+
case NType::NODE_256:
|
130
|
+
return Node256::InsertChild(art, node, byte, child);
|
131
|
+
default:
|
132
|
+
throw InternalException("Invalid node type for InsertChild.");
|
133
|
+
}
|
173
134
|
}
|
174
135
|
|
175
|
-
|
176
|
-
|
136
|
+
//===--------------------------------------------------------------------===//
|
137
|
+
// Deletes
|
138
|
+
//===--------------------------------------------------------------------===//
|
139
|
+
|
140
|
+
void Node::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
141
|
+
|
142
|
+
switch (node.DecodeARTNodeType()) {
|
143
|
+
case NType::NODE_4:
|
144
|
+
return Node4::DeleteChild(art, node, byte);
|
145
|
+
case NType::NODE_16:
|
146
|
+
return Node16::DeleteChild(art, node, byte);
|
147
|
+
case NType::NODE_48:
|
148
|
+
return Node48::DeleteChild(art, node, byte);
|
149
|
+
case NType::NODE_256:
|
150
|
+
return Node256::DeleteChild(art, node, byte);
|
151
|
+
default:
|
152
|
+
throw InternalException("Invalid node type for DeleteChild.");
|
153
|
+
}
|
177
154
|
}
|
178
155
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
156
|
+
//===--------------------------------------------------------------------===//
|
157
|
+
// Get functions
|
158
|
+
//===--------------------------------------------------------------------===//
|
159
|
+
|
160
|
+
optional_ptr<Node> Node::GetChild(ART &art, const uint8_t byte) const {
|
161
|
+
|
162
|
+
D_ASSERT(!IsSwizzled());
|
163
|
+
|
164
|
+
optional_ptr<Node> child;
|
165
|
+
switch (DecodeARTNodeType()) {
|
166
|
+
case NType::NODE_4: {
|
167
|
+
child = Node4::Get(art, *this).GetChild(byte);
|
186
168
|
break;
|
187
|
-
|
188
|
-
|
169
|
+
}
|
170
|
+
case NType::NODE_16: {
|
171
|
+
child = Node16::Get(art, *this).GetChild(byte);
|
189
172
|
break;
|
190
|
-
|
191
|
-
|
173
|
+
}
|
174
|
+
case NType::NODE_48: {
|
175
|
+
child = Node48::Get(art, *this).GetChild(byte);
|
192
176
|
break;
|
193
|
-
|
194
|
-
|
177
|
+
}
|
178
|
+
case NType::NODE_256: {
|
179
|
+
child = Node256::Get(art, *this).GetChild(byte);
|
195
180
|
break;
|
181
|
+
}
|
196
182
|
default:
|
197
|
-
throw InternalException("Invalid node type for
|
183
|
+
throw InternalException("Invalid node type for GetChild.");
|
184
|
+
}
|
185
|
+
|
186
|
+
// unswizzle the ART node before returning it
|
187
|
+
if (child && child->IsSwizzled()) {
|
188
|
+
child->Deserialize(art);
|
198
189
|
}
|
190
|
+
return child;
|
199
191
|
}
|
200
192
|
|
201
|
-
|
193
|
+
optional_ptr<Node> Node::GetNextChild(ART &art, uint8_t &byte) const {
|
202
194
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
case
|
208
|
-
|
195
|
+
D_ASSERT(!IsSwizzled());
|
196
|
+
|
197
|
+
optional_ptr<Node> child;
|
198
|
+
switch (DecodeARTNodeType()) {
|
199
|
+
case NType::NODE_4: {
|
200
|
+
child = Node4::Get(art, *this).GetNextChild(byte);
|
209
201
|
break;
|
210
|
-
|
211
|
-
|
202
|
+
}
|
203
|
+
case NType::NODE_16: {
|
204
|
+
child = Node16::Get(art, *this).GetNextChild(byte);
|
212
205
|
break;
|
213
|
-
|
214
|
-
|
206
|
+
}
|
207
|
+
case NType::NODE_48: {
|
208
|
+
child = Node48::Get(art, *this).GetNextChild(byte);
|
215
209
|
break;
|
216
|
-
|
217
|
-
|
210
|
+
}
|
211
|
+
case NType::NODE_256: {
|
212
|
+
child = Node256::Get(art, *this).GetNextChild(byte);
|
218
213
|
break;
|
219
214
|
}
|
215
|
+
default:
|
216
|
+
throw InternalException("Invalid node type for GetNextChild.");
|
217
|
+
}
|
220
218
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
auto child = GetChild(art, next_pos);
|
225
|
-
str += "(" + to_string(next_pos) + ", " + child->ToString(art) + ")";
|
226
|
-
next_pos = GetNextPos(next_pos);
|
219
|
+
// unswizzle the ART node before returning it
|
220
|
+
if (child && child->IsSwizzled()) {
|
221
|
+
child->Deserialize(art);
|
227
222
|
}
|
228
|
-
return
|
223
|
+
return child;
|
229
224
|
}
|
230
225
|
|
231
|
-
|
226
|
+
//===--------------------------------------------------------------------===//
|
227
|
+
// (De)serialization
|
228
|
+
//===--------------------------------------------------------------------===//
|
232
229
|
|
233
|
-
|
234
|
-
vector<BlockPointer> child_offsets;
|
235
|
-
for (idx_t i = 0; i < internal_type.children_size; i++) {
|
236
|
-
child_offsets.emplace_back(internal_type.children[i].Serialize(art, writer));
|
237
|
-
}
|
238
|
-
auto ptr = writer.GetBlockPointer();
|
230
|
+
BlockPointer Node::Serialize(ART &art, MetaBlockWriter &writer) {
|
239
231
|
|
240
|
-
|
241
|
-
|
242
|
-
|
232
|
+
if (!IsSet()) {
|
233
|
+
return {(block_id_t)DConstants::INVALID_INDEX, 0};
|
234
|
+
}
|
243
235
|
|
244
|
-
|
245
|
-
|
246
|
-
writer.Write(internal_type.key[i]);
|
236
|
+
if (IsSwizzled()) {
|
237
|
+
Deserialize(art);
|
247
238
|
}
|
248
239
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
240
|
+
switch (DecodeARTNodeType()) {
|
241
|
+
case NType::LEAF:
|
242
|
+
return Leaf::Get(art, *this).Serialize(art, writer);
|
243
|
+
case NType::NODE_4:
|
244
|
+
return Node4::Get(art, *this).Serialize(art, writer);
|
245
|
+
case NType::NODE_16:
|
246
|
+
return Node16::Get(art, *this).Serialize(art, writer);
|
247
|
+
case NType::NODE_48:
|
248
|
+
return Node48::Get(art, *this).Serialize(art, writer);
|
249
|
+
case NType::NODE_256:
|
250
|
+
return Node256::Get(art, *this).Serialize(art, writer);
|
251
|
+
default:
|
252
|
+
throw InternalException("Invalid node type for Serialize.");
|
253
253
|
}
|
254
|
-
return ptr;
|
255
254
|
}
|
256
255
|
|
257
|
-
|
256
|
+
void Node::Deserialize(ART &art) {
|
257
|
+
|
258
|
+
MetaBlockReader reader(art.table_io_manager.GetIndexBlockManager(), buffer_id);
|
259
|
+
reader.offset = offset;
|
260
|
+
type = reader.Read<uint8_t>();
|
261
|
+
swizzle_flag = 0;
|
262
|
+
|
263
|
+
auto type = DecodeARTNodeType();
|
264
|
+
SetPtr(Node::GetAllocator(art, type).New());
|
258
265
|
|
259
266
|
switch (type) {
|
260
|
-
case
|
261
|
-
|
262
|
-
case
|
263
|
-
|
264
|
-
|
265
|
-
return
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
return
|
270
|
-
}
|
267
|
+
case NType::LEAF:
|
268
|
+
return Leaf::Get(art, *this).Deserialize(art, reader);
|
269
|
+
case NType::NODE_4:
|
270
|
+
return Node4::Get(art, *this).Deserialize(art, reader);
|
271
|
+
case NType::NODE_16:
|
272
|
+
return Node16::Get(art, *this).Deserialize(art, reader);
|
273
|
+
case NType::NODE_48:
|
274
|
+
return Node48::Get(art, *this).Deserialize(art, reader);
|
275
|
+
case NType::NODE_256:
|
276
|
+
return Node256::Get(art, *this).Deserialize(art, reader);
|
271
277
|
default:
|
272
|
-
throw InternalException("Invalid
|
278
|
+
throw InternalException("Invalid node type for Deserialize.");
|
273
279
|
}
|
274
280
|
}
|
275
281
|
|
276
|
-
|
282
|
+
//===--------------------------------------------------------------------===//
|
283
|
+
// Utility
|
284
|
+
//===--------------------------------------------------------------------===//
|
277
285
|
|
278
|
-
|
279
|
-
count = reader.Read<uint16_t>();
|
280
|
-
prefix.Deserialize(reader);
|
286
|
+
string Node::ToString(ART &art) const {
|
281
287
|
|
282
|
-
|
283
|
-
|
284
|
-
|
288
|
+
D_ASSERT(!IsSwizzled());
|
289
|
+
|
290
|
+
if (DecodeARTNodeType() == NType::LEAF) {
|
291
|
+
return Leaf::Get(art, *this).ToString(art);
|
285
292
|
}
|
286
293
|
|
287
|
-
|
288
|
-
|
289
|
-
|
294
|
+
string str = "Node" + to_string(GetCapacity()) + ": [";
|
295
|
+
|
296
|
+
uint8_t byte = 0;
|
297
|
+
auto child = GetNextChild(art, byte);
|
298
|
+
while (child) {
|
299
|
+
str += "(" + to_string(byte) + ", " + child->ToString(art) + ")";
|
300
|
+
if (byte == NumericLimits<uint8_t>::Maximum()) {
|
301
|
+
break;
|
302
|
+
}
|
303
|
+
byte++;
|
304
|
+
child = GetNextChild(art, byte);
|
290
305
|
}
|
291
|
-
}
|
292
306
|
|
293
|
-
|
307
|
+
return str + "]";
|
308
|
+
}
|
294
309
|
|
295
|
-
|
296
|
-
reader.offset = offset;
|
310
|
+
idx_t Node::GetCapacity() const {
|
297
311
|
|
298
|
-
|
299
|
-
NodeType node_type((NodeType)(n));
|
312
|
+
D_ASSERT(!IsSwizzled());
|
300
313
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
return
|
308
|
-
|
309
|
-
|
310
|
-
deserialized_node = (Node *)Node4::New();
|
311
|
-
break;
|
312
|
-
}
|
313
|
-
case NodeType::N16: {
|
314
|
-
deserialized_node = (Node *)Node16::New();
|
315
|
-
break;
|
316
|
-
}
|
317
|
-
case NodeType::N48: {
|
318
|
-
deserialized_node = (Node *)Node48::New();
|
319
|
-
break;
|
320
|
-
}
|
321
|
-
case NodeType::N256: {
|
322
|
-
deserialized_node = (Node *)Node256::New();
|
323
|
-
break;
|
324
|
-
}
|
314
|
+
switch (DecodeARTNodeType()) {
|
315
|
+
case NType::NODE_4:
|
316
|
+
return Node::NODE_4_CAPACITY;
|
317
|
+
case NType::NODE_16:
|
318
|
+
return Node::NODE_16_CAPACITY;
|
319
|
+
case NType::NODE_48:
|
320
|
+
return Node::NODE_48_CAPACITY;
|
321
|
+
case NType::NODE_256:
|
322
|
+
return Node::NODE_256_CAPACITY;
|
325
323
|
default:
|
326
|
-
throw InternalException("
|
324
|
+
throw InternalException("Invalid node type for GetCapacity.");
|
327
325
|
}
|
328
|
-
deserialized_node->DeserializeInternal(art, reader);
|
329
|
-
art.IncreaseMemorySize(deserialized_node->MemorySize(art, false));
|
330
|
-
return deserialized_node;
|
331
326
|
}
|
332
327
|
|
333
|
-
|
334
|
-
|
335
|
-
|
328
|
+
Prefix &Node::GetPrefix(ART &art) {
|
329
|
+
|
330
|
+
if (IsSwizzled()) {
|
331
|
+
Deserialize(art);
|
336
332
|
}
|
337
|
-
|
338
|
-
|
333
|
+
|
334
|
+
switch (DecodeARTNodeType()) {
|
335
|
+
case NType::LEAF:
|
336
|
+
return Leaf::Get(art, *this).prefix;
|
337
|
+
case NType::NODE_4:
|
338
|
+
return Node4::Get(art, *this).prefix;
|
339
|
+
case NType::NODE_16:
|
340
|
+
return Node16::Get(art, *this).prefix;
|
341
|
+
case NType::NODE_48:
|
342
|
+
return Node48::Get(art, *this).prefix;
|
343
|
+
case NType::NODE_256:
|
344
|
+
return Node256::Get(art, *this).prefix;
|
345
|
+
default:
|
346
|
+
throw InternalException("Invalid node type for GetPrefix.");
|
339
347
|
}
|
340
348
|
}
|
341
349
|
|
342
|
-
|
343
|
-
bool ResolvePrefixesAndMerge(MergeInfo &info, ParentsOfNodes &parents);
|
350
|
+
NType Node::GetARTNodeTypeByCount(const idx_t count) {
|
344
351
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
352
|
+
if (count <= NODE_4_CAPACITY) {
|
353
|
+
return NType::NODE_4;
|
354
|
+
} else if (count <= NODE_16_CAPACITY) {
|
355
|
+
return NType::NODE_16;
|
356
|
+
} else if (count <= NODE_48_CAPACITY) {
|
357
|
+
return NType::NODE_48;
|
358
|
+
}
|
359
|
+
return NType::NODE_256;
|
360
|
+
}
|
354
361
|
|
355
|
-
|
356
|
-
|
357
|
-
swap(info.l_node, info.r_node);
|
358
|
-
UpdateParentsOfNodes(info.l_node, info.r_node, parents);
|
362
|
+
FixedSizeAllocator &Node::GetAllocator(const ART &art, NType type) {
|
363
|
+
return *art.allocators[(uint8_t)type - 1];
|
359
364
|
}
|
360
365
|
|
361
|
-
|
366
|
+
//===--------------------------------------------------------------------===//
|
367
|
+
// Merging
|
368
|
+
//===--------------------------------------------------------------------===//
|
362
369
|
|
363
|
-
|
364
|
-
D_ASSERT(info.r_node);
|
370
|
+
void Node::InitializeMerge(ART &art, const ARTFlags &flags) {
|
365
371
|
|
366
|
-
|
367
|
-
|
368
|
-
|
372
|
+
if (!IsSet()) {
|
373
|
+
return;
|
374
|
+
}
|
369
375
|
|
370
|
-
if (
|
371
|
-
|
372
|
-
SwapNodes(info, parents);
|
376
|
+
if (IsSwizzled()) {
|
377
|
+
Deserialize(art);
|
373
378
|
}
|
374
379
|
|
375
|
-
if
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
+
// if not all prefixes are inlined
|
381
|
+
if (flags.merge_buffer_counts[(uint8_t)NType::PREFIX_SEGMENT - 1] != 0) {
|
382
|
+
// initialize prefix segments
|
383
|
+
GetPrefix(art).InitializeMerge(art, flags.merge_buffer_counts[(uint8_t)NType::PREFIX_SEGMENT - 1]);
|
384
|
+
}
|
385
|
+
|
386
|
+
auto type = DecodeARTNodeType();
|
387
|
+
switch (type) {
|
388
|
+
case NType::LEAF:
|
389
|
+
// if not all leaves are inlined
|
390
|
+
if (flags.merge_buffer_counts[(uint8_t)NType::LEAF_SEGMENT - 1] != 0) {
|
391
|
+
// initialize leaf segments
|
392
|
+
Leaf::Get(art, *this).InitializeMerge(art, flags.merge_buffer_counts[(uint8_t)NType::LEAF_SEGMENT - 1]);
|
380
393
|
}
|
381
|
-
|
382
|
-
|
394
|
+
break;
|
395
|
+
case NType::NODE_4:
|
396
|
+
Node4::Get(art, *this).InitializeMerge(art, flags);
|
397
|
+
break;
|
398
|
+
case NType::NODE_16:
|
399
|
+
Node16::Get(art, *this).InitializeMerge(art, flags);
|
400
|
+
break;
|
401
|
+
case NType::NODE_48:
|
402
|
+
Node48::Get(art, *this).InitializeMerge(art, flags);
|
403
|
+
break;
|
404
|
+
case NType::NODE_256:
|
405
|
+
Node256::Get(art, *this).InitializeMerge(art, flags);
|
406
|
+
break;
|
407
|
+
default:
|
408
|
+
throw InternalException("Invalid node type for InitializeMerge.");
|
383
409
|
}
|
384
410
|
|
385
|
-
uint8_t
|
386
|
-
|
411
|
+
buffer_id += flags.merge_buffer_counts[(uint8_t)type - 1];
|
412
|
+
}
|
387
413
|
|
388
|
-
|
389
|
-
r_child_pos = info.r_node->GetNextPosAndByte(r_child_pos, key_byte);
|
390
|
-
if (r_child_pos == DConstants::INVALID_INDEX) {
|
391
|
-
break;
|
392
|
-
}
|
393
|
-
auto r_child = info.r_node->GetChild(*info.r_art, r_child_pos);
|
394
|
-
auto l_child_pos = info.l_node->GetChildPos(key_byte);
|
395
|
-
|
396
|
-
if (l_child_pos == DConstants::INVALID_INDEX) {
|
397
|
-
// insert child at empty position
|
398
|
-
auto r_memory_size = r_child->MemorySize(*info.r_art, true);
|
399
|
-
Node::InsertChild(*info.root_l_art, info.l_node, key_byte, r_child);
|
400
|
-
|
401
|
-
info.root_l_art->IncreaseMemorySize(r_memory_size);
|
402
|
-
info.root_r_art->DecreaseMemorySize(r_memory_size);
|
403
|
-
if (parents.l_parent) {
|
404
|
-
parents.l_parent->ReplaceChildPointer(parents.l_pos, info.l_node);
|
405
|
-
}
|
406
|
-
info.r_node->ReplaceChildPointer(r_child_pos, nullptr);
|
414
|
+
bool Node::Merge(ART &art, Node &other) {
|
407
415
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
ParentsOfNodes child_parents(info.l_node, l_child_pos, info.r_node, r_child_pos);
|
413
|
-
if (!ResolvePrefixesAndMerge(child_info, child_parents)) {
|
414
|
-
return false;
|
415
|
-
}
|
416
|
-
}
|
416
|
+
if (!IsSet()) {
|
417
|
+
*this = other;
|
418
|
+
other = Node();
|
419
|
+
return true;
|
417
420
|
}
|
418
|
-
|
421
|
+
|
422
|
+
return ResolvePrefixes(art, other);
|
419
423
|
}
|
420
424
|
|
421
|
-
bool
|
425
|
+
bool Node::ResolvePrefixes(ART &art, Node &other) {
|
426
|
+
|
422
427
|
// NOTE: we always merge into the left ART
|
423
428
|
|
424
|
-
D_ASSERT(
|
425
|
-
D_ASSERT(
|
429
|
+
D_ASSERT(IsSet());
|
430
|
+
D_ASSERT(other.IsSet());
|
426
431
|
|
427
432
|
// make sure that r_node has the longer (or equally long) prefix
|
428
|
-
if (
|
429
|
-
|
433
|
+
if (GetPrefix(art).count > other.GetPrefix(art).count) {
|
434
|
+
swap(*this, other);
|
430
435
|
}
|
431
436
|
|
432
|
-
|
433
|
-
auto &
|
434
|
-
auto &
|
435
|
-
auto
|
436
|
-
auto r_prefix_size = r_node->prefix.Size();
|
437
|
+
auto &l_node = *this;
|
438
|
+
auto &r_node = other;
|
439
|
+
auto &l_prefix = l_node.GetPrefix(art);
|
440
|
+
auto &r_prefix = r_node.GetPrefix(art);
|
437
441
|
|
438
|
-
auto
|
442
|
+
auto mismatch_position = l_prefix.MismatchPosition(art, r_prefix);
|
439
443
|
|
440
444
|
// both nodes have no prefix or the same prefix
|
441
|
-
if (
|
442
|
-
return
|
445
|
+
if (mismatch_position == l_prefix.count && l_prefix.count == r_prefix.count) {
|
446
|
+
return MergeInternal(art, r_node);
|
443
447
|
}
|
444
448
|
|
445
|
-
if (
|
449
|
+
if (mismatch_position == l_prefix.count) {
|
446
450
|
// r_node's prefix contains l_node's prefix
|
447
451
|
// l_node cannot be a leaf, otherwise the key represented by l_node would be a subset of another key
|
448
452
|
// which is not possible by our construction
|
449
|
-
D_ASSERT(l_node
|
453
|
+
D_ASSERT(l_node.DecodeARTNodeType() != NType::LEAF);
|
450
454
|
|
451
|
-
// test if the next byte (
|
452
|
-
auto mismatch_byte =
|
453
|
-
auto
|
455
|
+
// test if the next byte (mismatch_position) in r_node (longer prefix) exists in l_node
|
456
|
+
auto mismatch_byte = r_prefix.GetByte(art, mismatch_position);
|
457
|
+
auto child_node = l_node.GetChild(art, mismatch_byte);
|
454
458
|
|
455
|
-
// update the prefix of r_node to only consist of the bytes after
|
456
|
-
|
459
|
+
// update the prefix of r_node to only consist of the bytes after mismatch_position
|
460
|
+
r_prefix.Reduce(art, mismatch_position);
|
457
461
|
|
458
462
|
// insert r_node as a child of l_node at empty position
|
459
|
-
if (
|
460
|
-
|
461
|
-
|
462
|
-
Node::InsertChild(*info.root_l_art, l_node, mismatch_byte, r_node);
|
463
|
-
|
464
|
-
info.root_l_art->IncreaseMemorySize(r_memory_size);
|
465
|
-
info.root_r_art->DecreaseMemorySize(r_memory_size);
|
466
|
-
UpdateParentsOfNodes(l_node, null_parent, parents);
|
467
|
-
r_node = nullptr;
|
463
|
+
if (!child_node) {
|
464
|
+
Node::InsertChild(art, l_node, mismatch_byte, r_node);
|
465
|
+
r_node.Reset();
|
468
466
|
return true;
|
469
467
|
}
|
470
468
|
|
471
469
|
// recurse
|
472
|
-
|
473
|
-
MergeInfo child_info(info.l_art, info.r_art, info.root_l_art, info.root_r_art, child_node, r_node);
|
474
|
-
ParentsOfNodes child_parents(l_node, child_pos, parents.r_parent, parents.r_pos);
|
475
|
-
return ResolvePrefixesAndMerge(child_info, child_parents);
|
470
|
+
return child_node->ResolvePrefixes(art, r_node);
|
476
471
|
}
|
477
472
|
|
478
473
|
// prefixes differ, create new node and insert both nodes as children
|
479
474
|
|
480
475
|
// create new node
|
481
|
-
|
482
|
-
|
483
|
-
|
476
|
+
auto old_l_node = l_node;
|
477
|
+
auto &new_n4 = Node4::New(art, l_node);
|
478
|
+
new_n4.prefix.Initialize(art, l_prefix, mismatch_position);
|
484
479
|
|
485
|
-
// insert l_node, break up prefix of l_node
|
486
|
-
auto key_byte =
|
487
|
-
Node4::InsertChild(
|
480
|
+
// insert old l_node, break up prefix of old l_node
|
481
|
+
auto key_byte = l_prefix.Reduce(art, mismatch_position);
|
482
|
+
Node4::InsertChild(art, l_node, key_byte, old_l_node);
|
488
483
|
|
489
484
|
// insert r_node, break up prefix of r_node
|
490
|
-
key_byte =
|
491
|
-
|
492
|
-
Node4::InsertChild(*info.root_l_art, new_node, key_byte, r_node);
|
485
|
+
key_byte = r_prefix.Reduce(art, mismatch_position);
|
486
|
+
Node4::InsertChild(art, l_node, key_byte, r_node);
|
493
487
|
|
494
|
-
|
495
|
-
info.root_r_art->DecreaseMemorySize(r_memory_size);
|
496
|
-
|
497
|
-
l_node = new_node;
|
498
|
-
UpdateParentsOfNodes(l_node, null_parent, parents);
|
499
|
-
r_node = nullptr;
|
488
|
+
r_node.Reset();
|
500
489
|
return true;
|
501
490
|
}
|
502
491
|
|
503
|
-
bool Node::
|
492
|
+
bool Node::MergeInternal(ART &art, Node &other) {
|
504
493
|
|
505
|
-
|
506
|
-
|
507
|
-
ParentsOfNodes parents(null_parent, 0, null_parent, 0);
|
508
|
-
return ResolvePrefixesAndMerge(info, parents);
|
509
|
-
}
|
494
|
+
D_ASSERT(IsSet());
|
495
|
+
D_ASSERT(other.IsSet());
|
510
496
|
|
511
|
-
|
497
|
+
// always try to merge the smaller node into the bigger node
|
498
|
+
// because maybe there is enough free space in the bigger node to fit the smaller one
|
499
|
+
// without too much recursion
|
500
|
+
if (this->DecodeARTNodeType() < other.DecodeARTNodeType()) {
|
501
|
+
swap(*this, other);
|
502
|
+
}
|
512
503
|
|
513
|
-
|
514
|
-
auto
|
504
|
+
Node empty_node;
|
505
|
+
auto &l_node = *this;
|
506
|
+
auto &r_node = other;
|
507
|
+
|
508
|
+
if (r_node.DecodeARTNodeType() == NType::LEAF) {
|
509
|
+
D_ASSERT(l_node.DecodeARTNodeType() == NType::LEAF);
|
510
|
+
|
511
|
+
if (art.IsUnique()) {
|
512
|
+
return false;
|
513
|
+
}
|
514
|
+
|
515
|
+
Leaf::Get(art, *this).Merge(art, r_node);
|
516
|
+
return true;
|
517
|
+
}
|
518
|
+
|
519
|
+
uint8_t byte = 0;
|
520
|
+
auto r_child = r_node.GetNextChild(art, byte);
|
521
|
+
|
522
|
+
// while r_node still has children to merge
|
523
|
+
while (r_child) {
|
524
|
+
auto l_child = l_node.GetChild(art, byte);
|
525
|
+
if (!l_child) {
|
526
|
+
// insert child at empty byte
|
527
|
+
Node::InsertChild(art, l_node, byte, *r_child);
|
528
|
+
r_node.ReplaceChild(art, byte, empty_node);
|
529
|
+
|
530
|
+
} else {
|
531
|
+
// recurse
|
532
|
+
if (!l_child->ResolvePrefixes(art, *r_child)) {
|
533
|
+
return false;
|
534
|
+
}
|
535
|
+
}
|
515
536
|
|
516
|
-
|
517
|
-
|
518
|
-
if (ChildIsInMemory(next_pos)) {
|
519
|
-
auto child = GetChild(art, next_pos);
|
520
|
-
memory_size_children += child->MemorySize(art, true);
|
537
|
+
if (byte == NumericLimits<uint8_t>::Maximum()) {
|
538
|
+
break;
|
521
539
|
}
|
522
|
-
|
540
|
+
byte++;
|
541
|
+
r_child = r_node.GetNextChild(art, byte);
|
523
542
|
}
|
524
543
|
|
525
|
-
|
544
|
+
Node::Free(art, r_node);
|
545
|
+
return true;
|
546
|
+
}
|
547
|
+
|
548
|
+
//===--------------------------------------------------------------------===//
|
549
|
+
// Vacuum
|
550
|
+
//===--------------------------------------------------------------------===//
|
551
|
+
|
552
|
+
void Node::Vacuum(ART &art, Node &node, const ARTFlags &flags) {
|
553
|
+
|
554
|
+
if (node.IsSwizzled()) {
|
555
|
+
return;
|
556
|
+
}
|
557
|
+
|
558
|
+
// possibly vacuum prefix segments, if not all prefixes are inlined
|
559
|
+
bool needs_vacuum = flags.vacuum_flags[(uint8_t)NType::PREFIX_SEGMENT - 1];
|
560
|
+
if (needs_vacuum) {
|
561
|
+
// vacuum prefix segments
|
562
|
+
node.GetPrefix(art).Vacuum(art);
|
563
|
+
}
|
564
|
+
|
565
|
+
auto type = node.DecodeARTNodeType();
|
566
|
+
auto &allocator = Node::GetAllocator(art, type);
|
567
|
+
needs_vacuum = flags.vacuum_flags[node.type - 1] && allocator.NeedsVacuum(node);
|
568
|
+
if (needs_vacuum) {
|
569
|
+
node.SetPtr(allocator.VacuumPointer(node));
|
570
|
+
}
|
571
|
+
|
572
|
+
switch (type) {
|
573
|
+
case NType::LEAF: {
|
574
|
+
// possibly vacuum leaf segments, if not all leaves are inlined
|
575
|
+
if (flags.vacuum_flags[(uint8_t)NType::LEAF_SEGMENT - 1]) {
|
576
|
+
Leaf::Get(art, node).Vacuum(art);
|
577
|
+
}
|
578
|
+
return;
|
579
|
+
}
|
580
|
+
case NType::NODE_4:
|
581
|
+
return Node4::Get(art, node).Vacuum(art, flags);
|
582
|
+
case NType::NODE_16:
|
583
|
+
return Node16::Get(art, node).Vacuum(art, flags);
|
584
|
+
case NType::NODE_48:
|
585
|
+
return Node48::Get(art, node).Vacuum(art, flags);
|
586
|
+
case NType::NODE_256:
|
587
|
+
return Node256::Get(art, node).Vacuum(art, flags);
|
588
|
+
default:
|
589
|
+
throw InternalException("Invalid node type for Vacuum.");
|
590
|
+
}
|
526
591
|
}
|
527
592
|
|
528
593
|
} // namespace duckdb
|