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,170 +1,234 @@
|
|
1
1
|
#include "duckdb/execution/index/art/node16.hpp"
|
2
2
|
|
3
3
|
#include "duckdb/execution/index/art/art.hpp"
|
4
|
+
#include "duckdb/execution/index/art/node.hpp"
|
4
5
|
#include "duckdb/execution/index/art/node4.hpp"
|
5
6
|
#include "duckdb/execution/index/art/node48.hpp"
|
6
|
-
|
7
|
-
#include
|
7
|
+
#include "duckdb/storage/meta_block_reader.hpp"
|
8
|
+
#include "duckdb/storage/meta_block_writer.hpp"
|
8
9
|
|
9
10
|
namespace duckdb {
|
10
11
|
|
11
|
-
Node16::
|
12
|
-
|
12
|
+
Node16 &Node16::New(ART &art, Node &node) {
|
13
|
+
|
14
|
+
node.SetPtr(Node::GetAllocator(art, NType::NODE_16).New());
|
15
|
+
node.type = (uint8_t)NType::NODE_16;
|
16
|
+
auto &n16 = Node16::Get(art, node);
|
17
|
+
|
18
|
+
n16.count = 0;
|
19
|
+
n16.prefix.Initialize();
|
20
|
+
return n16;
|
13
21
|
}
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
23
|
+
void Node16::Free(ART &art, Node &node) {
|
24
|
+
|
25
|
+
D_ASSERT(node.IsSet());
|
26
|
+
D_ASSERT(!node.IsSwizzled());
|
27
|
+
|
28
|
+
auto &n16 = Node16::Get(art, node);
|
29
|
+
|
30
|
+
// free all children
|
31
|
+
for (idx_t i = 0; i < n16.count; i++) {
|
32
|
+
Node::Free(art, n16.children[i]);
|
18
33
|
}
|
19
|
-
return prefix.MemorySize() + sizeof(*this);
|
20
34
|
}
|
21
35
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
36
|
+
Node16 &Node16::GrowNode4(ART &art, Node &node16, Node &node4) {
|
37
|
+
|
38
|
+
auto &n4 = Node4::Get(art, node4);
|
39
|
+
auto &n16 = Node16::New(art, node16);
|
40
|
+
|
41
|
+
n16.count = n4.count;
|
42
|
+
n16.prefix.Move(n4.prefix);
|
43
|
+
|
44
|
+
for (idx_t i = 0; i < n4.count; i++) {
|
45
|
+
n16.key[i] = n4.key[i];
|
46
|
+
n16.children[i] = n4.children[i];
|
27
47
|
}
|
28
|
-
|
48
|
+
|
49
|
+
n4.count = 0;
|
50
|
+
Node::Free(art, node4);
|
51
|
+
return n16;
|
29
52
|
}
|
30
53
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
equal = true;
|
36
|
-
} else {
|
37
|
-
equal = false;
|
38
|
-
}
|
54
|
+
Node16 &Node16::ShrinkNode48(ART &art, Node &node16, Node &node48) {
|
55
|
+
|
56
|
+
auto &n16 = Node16::New(art, node16);
|
57
|
+
auto &n48 = Node48::Get(art, node48);
|
39
58
|
|
40
|
-
|
59
|
+
n16.count = 0;
|
60
|
+
n16.prefix.Move(n48.prefix);
|
61
|
+
|
62
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
63
|
+
if (n48.child_index[i] != Node::EMPTY_MARKER) {
|
64
|
+
n16.key[n16.count] = i;
|
65
|
+
n16.children[n16.count] = n48.children[n48.child_index[i]];
|
66
|
+
n16.count++;
|
41
67
|
}
|
42
68
|
}
|
43
|
-
return DConstants::INVALID_INDEX;
|
44
|
-
}
|
45
69
|
|
46
|
-
|
47
|
-
|
70
|
+
n48.count = 0;
|
71
|
+
Node::Free(art, node48);
|
72
|
+
return n16;
|
48
73
|
}
|
49
74
|
|
50
|
-
|
51
|
-
if (pos == DConstants::INVALID_INDEX) {
|
52
|
-
return 0;
|
53
|
-
}
|
54
|
-
pos++;
|
55
|
-
return pos < count ? pos : DConstants::INVALID_INDEX;
|
56
|
-
}
|
75
|
+
void Node16::InitializeMerge(ART &art, const ARTFlags &flags) {
|
57
76
|
|
58
|
-
|
59
|
-
|
60
|
-
byte = key[0];
|
61
|
-
return 0;
|
77
|
+
for (idx_t i = 0; i < count; i++) {
|
78
|
+
children[i].InitializeMerge(art, flags);
|
62
79
|
}
|
63
|
-
pos++;
|
64
|
-
if (pos < count) {
|
65
|
-
byte = key[pos];
|
66
|
-
return pos;
|
67
|
-
}
|
68
|
-
return DConstants::INVALID_INDEX;
|
69
|
-
}
|
70
|
-
|
71
|
-
Node *Node16::GetChild(ART &art, idx_t pos) {
|
72
|
-
D_ASSERT(pos < count);
|
73
|
-
return children[pos].Unswizzle(art);
|
74
80
|
}
|
75
81
|
|
76
|
-
void Node16::
|
77
|
-
children[pos] = node;
|
78
|
-
}
|
82
|
+
void Node16::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
84
|
+
D_ASSERT(node.IsSet());
|
85
|
+
D_ASSERT(!node.IsSwizzled());
|
86
|
+
auto &n16 = Node16::Get(art, node);
|
83
87
|
|
84
|
-
|
85
|
-
|
88
|
+
// ensure that there is no other child at the same byte
|
89
|
+
for (idx_t i = 0; i < n16.count; i++) {
|
90
|
+
D_ASSERT(n16.key[i] != byte);
|
91
|
+
}
|
86
92
|
|
87
93
|
// insert new child node into node
|
88
|
-
if (
|
94
|
+
if (n16.count < Node::NODE_16_CAPACITY) {
|
89
95
|
// still space, just insert the child
|
90
|
-
idx_t
|
91
|
-
while (
|
92
|
-
|
96
|
+
idx_t child_pos = 0;
|
97
|
+
while (child_pos < n16.count && n16.key[child_pos] < byte) {
|
98
|
+
child_pos++;
|
93
99
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
}
|
100
|
+
// move children backwards to make space
|
101
|
+
for (idx_t i = n16.count; i > child_pos; i--) {
|
102
|
+
n16.key[i] = n16.key[i - 1];
|
103
|
+
n16.children[i] = n16.children[i - 1];
|
99
104
|
}
|
100
|
-
|
101
|
-
|
102
|
-
|
105
|
+
|
106
|
+
n16.key[child_pos] = byte;
|
107
|
+
n16.children[child_pos] = child;
|
108
|
+
n16.count++;
|
103
109
|
|
104
110
|
} else {
|
105
111
|
// node is full, grow to Node48
|
106
|
-
auto
|
107
|
-
|
108
|
-
|
109
|
-
new_node->prefix = std::move(n->prefix);
|
110
|
-
|
111
|
-
for (idx_t i = 0; i < node->count; i++) {
|
112
|
-
new_node->child_index[n->key[i]] = i;
|
113
|
-
new_node->children[i] = n->children[i];
|
114
|
-
n->children[i] = nullptr;
|
115
|
-
}
|
116
|
-
|
117
|
-
art.DecreaseMemorySize(node->MemorySize(art, false));
|
118
|
-
Node::Delete(node);
|
119
|
-
node = new_node;
|
120
|
-
Node48::InsertChild(art, node, key_byte, new_child);
|
112
|
+
auto node16 = node;
|
113
|
+
Node48::GrowNode16(art, node, node16);
|
114
|
+
Node48::InsertChild(art, node, byte, child);
|
121
115
|
}
|
122
116
|
}
|
123
117
|
|
124
|
-
void Node16::
|
118
|
+
void Node16::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
125
119
|
|
126
|
-
|
127
|
-
D_ASSERT(
|
120
|
+
D_ASSERT(node.IsSet());
|
121
|
+
D_ASSERT(!node.IsSwizzled());
|
122
|
+
auto &n16 = Node16::Get(art, node);
|
128
123
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
124
|
+
idx_t child_pos = 0;
|
125
|
+
for (; child_pos < n16.count; child_pos++) {
|
126
|
+
if (n16.key[child_pos] == byte) {
|
127
|
+
break;
|
128
|
+
}
|
133
129
|
}
|
134
130
|
|
135
|
-
|
136
|
-
|
137
|
-
|
131
|
+
D_ASSERT(child_pos < n16.count);
|
132
|
+
|
133
|
+
// free the child and decrease the count
|
134
|
+
Node::Free(art, n16.children[child_pos]);
|
135
|
+
n16.count--;
|
138
136
|
|
139
137
|
// potentially move any children backwards
|
140
|
-
for (;
|
141
|
-
|
142
|
-
|
138
|
+
for (idx_t i = child_pos; i < n16.count; i++) {
|
139
|
+
n16.key[i] = n16.key[i + 1];
|
140
|
+
n16.children[i] = n16.children[i + 1];
|
143
141
|
}
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
|
143
|
+
// shrink node to Node4
|
144
|
+
if (n16.count < Node::NODE_4_CAPACITY) {
|
145
|
+
auto node16 = node;
|
146
|
+
Node4::ShrinkNode16(art, node, node16);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
void Node16::ReplaceChild(const uint8_t byte, const Node child) {
|
151
|
+
for (idx_t i = 0; i < count; i++) {
|
152
|
+
if (key[i] == byte) {
|
153
|
+
children[i] = child;
|
154
|
+
return;
|
148
155
|
}
|
149
|
-
n->children[pos] = nullptr;
|
150
156
|
}
|
157
|
+
}
|
151
158
|
|
152
|
-
|
153
|
-
|
159
|
+
optional_ptr<Node> Node16::GetChild(const uint8_t byte) {
|
160
|
+
|
161
|
+
for (idx_t i = 0; i < count; i++) {
|
162
|
+
if (key[i] == byte) {
|
163
|
+
return &children[i];
|
164
|
+
}
|
165
|
+
}
|
166
|
+
return nullptr;
|
167
|
+
}
|
154
168
|
|
155
|
-
|
156
|
-
art.IncreaseMemorySize(new_node->MemorySize(art, false));
|
157
|
-
new_node->prefix = std::move(n->prefix);
|
169
|
+
optional_ptr<Node> Node16::GetNextChild(uint8_t &byte) {
|
158
170
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
171
|
+
for (idx_t i = 0; i < count; i++) {
|
172
|
+
if (key[i] >= byte) {
|
173
|
+
byte = key[i];
|
174
|
+
return &children[i];
|
163
175
|
}
|
176
|
+
}
|
177
|
+
return nullptr;
|
178
|
+
}
|
179
|
+
|
180
|
+
BlockPointer Node16::Serialize(ART &art, MetaBlockWriter &writer) {
|
181
|
+
|
182
|
+
// recurse into children and retrieve child block pointers
|
183
|
+
vector<BlockPointer> child_block_pointers;
|
184
|
+
for (idx_t i = 0; i < count; i++) {
|
185
|
+
child_block_pointers.push_back(children[i].Serialize(art, writer));
|
186
|
+
}
|
187
|
+
for (idx_t i = count; i < Node::NODE_16_CAPACITY; i++) {
|
188
|
+
child_block_pointers.emplace_back((block_id_t)DConstants::INVALID_INDEX, 0);
|
189
|
+
}
|
190
|
+
|
191
|
+
// get pointer and write fields
|
192
|
+
auto block_pointer = writer.GetBlockPointer();
|
193
|
+
writer.Write(NType::NODE_16);
|
194
|
+
writer.Write<uint8_t>(count);
|
195
|
+
prefix.Serialize(art, writer);
|
164
196
|
|
165
|
-
|
166
|
-
|
167
|
-
|
197
|
+
// write key values
|
198
|
+
for (idx_t i = 0; i < Node::NODE_16_CAPACITY; i++) {
|
199
|
+
writer.Write(key[i]);
|
168
200
|
}
|
201
|
+
|
202
|
+
// write child block pointers
|
203
|
+
for (auto &child_block_pointer : child_block_pointers) {
|
204
|
+
writer.Write(child_block_pointer.block_id);
|
205
|
+
writer.Write(child_block_pointer.offset);
|
206
|
+
}
|
207
|
+
|
208
|
+
return block_pointer;
|
169
209
|
}
|
210
|
+
|
211
|
+
void Node16::Deserialize(ART &art, MetaBlockReader &reader) {
|
212
|
+
|
213
|
+
count = reader.Read<uint8_t>();
|
214
|
+
prefix.Deserialize(art, reader);
|
215
|
+
|
216
|
+
// read key values
|
217
|
+
for (idx_t i = 0; i < Node::NODE_16_CAPACITY; i++) {
|
218
|
+
key[i] = reader.Read<uint8_t>();
|
219
|
+
}
|
220
|
+
|
221
|
+
// read child block pointers
|
222
|
+
for (idx_t i = 0; i < Node::NODE_16_CAPACITY; i++) {
|
223
|
+
children[i] = Node(reader);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
void Node16::Vacuum(ART &art, const ARTFlags &flags) {
|
228
|
+
|
229
|
+
for (idx_t i = 0; i < count; i++) {
|
230
|
+
Node::Vacuum(art, children[i], flags);
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
170
234
|
} // namespace duckdb
|
@@ -1,122 +1,160 @@
|
|
1
1
|
#include "duckdb/execution/index/art/node256.hpp"
|
2
2
|
|
3
3
|
#include "duckdb/execution/index/art/art.hpp"
|
4
|
+
#include "duckdb/execution/index/art/node.hpp"
|
4
5
|
#include "duckdb/execution/index/art/node48.hpp"
|
6
|
+
#include "duckdb/storage/meta_block_reader.hpp"
|
7
|
+
#include "duckdb/storage/meta_block_writer.hpp"
|
5
8
|
|
6
9
|
namespace duckdb {
|
7
10
|
|
8
|
-
Node256::
|
9
|
-
}
|
11
|
+
Node256 &Node256::New(ART &art, Node &node) {
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
}
|
15
|
-
return prefix.MemorySize() + sizeof(*this);
|
16
|
-
}
|
13
|
+
node.SetPtr(Node::GetAllocator(art, NType::NODE_256).New());
|
14
|
+
node.type = (uint8_t)NType::NODE_256;
|
15
|
+
auto &n256 = Node256::Get(art, node);
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
n256.count = 0;
|
18
|
+
n256.prefix.Initialize();
|
19
|
+
|
20
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
21
|
+
n256.children[i].Reset();
|
23
22
|
}
|
23
|
+
|
24
|
+
return n256;
|
24
25
|
}
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
27
|
+
void Node256::Free(ART &art, Node &node) {
|
28
|
+
|
29
|
+
D_ASSERT(node.IsSet());
|
30
|
+
D_ASSERT(!node.IsSwizzled());
|
31
|
+
|
32
|
+
auto &n256 = Node256::Get(art, node);
|
33
|
+
|
34
|
+
if (!n256.count) {
|
35
|
+
return;
|
36
36
|
}
|
37
|
-
return DConstants::INVALID_INDEX;
|
38
|
-
}
|
39
37
|
|
40
|
-
|
41
|
-
for (idx_t i = 0; i <
|
42
|
-
if (children[i]) {
|
43
|
-
|
38
|
+
// free all children
|
39
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
40
|
+
if (n256.children[i].IsSet()) {
|
41
|
+
Node::Free(art, n256.children[i]);
|
44
42
|
}
|
45
43
|
}
|
46
|
-
return DConstants::INVALID_INDEX;
|
47
44
|
}
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
Node256 &Node256::GrowNode48(ART &art, Node &node256, Node &node48) {
|
47
|
+
|
48
|
+
auto &n48 = Node48::Get(art, node48);
|
49
|
+
auto &n256 = Node256::New(art, node256);
|
50
|
+
|
51
|
+
n256.count = n48.count;
|
52
|
+
n256.prefix.Move(n48.prefix);
|
53
|
+
|
54
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
55
|
+
if (n48.child_index[i] != Node::EMPTY_MARKER) {
|
56
|
+
n256.children[i] = n48.children[n48.child_index[i]];
|
57
|
+
} else {
|
58
|
+
n256.children[i].Reset();
|
54
59
|
}
|
55
60
|
}
|
56
|
-
|
61
|
+
|
62
|
+
n48.count = 0;
|
63
|
+
Node::Free(art, node48);
|
64
|
+
return n256;
|
57
65
|
}
|
58
66
|
|
59
|
-
|
60
|
-
|
61
|
-
for (;
|
62
|
-
if (children[
|
63
|
-
|
64
|
-
return pos;
|
67
|
+
void Node256::InitializeMerge(ART &art, const ARTFlags &flags) {
|
68
|
+
|
69
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
70
|
+
if (children[i].IsSet()) {
|
71
|
+
children[i].InitializeMerge(art, flags);
|
65
72
|
}
|
66
73
|
}
|
67
|
-
return Node::GetNextPos(pos);
|
68
74
|
}
|
69
75
|
|
70
|
-
|
71
|
-
|
76
|
+
void Node256::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
|
77
|
+
|
78
|
+
D_ASSERT(node.IsSet());
|
79
|
+
D_ASSERT(!node.IsSwizzled());
|
80
|
+
auto &n256 = Node256::Get(art, node);
|
81
|
+
|
82
|
+
// ensure that there is no other child at the same byte
|
83
|
+
D_ASSERT(!n256.children[byte].IsSet());
|
84
|
+
|
85
|
+
n256.count++;
|
86
|
+
n256.children[byte] = child;
|
72
87
|
}
|
73
88
|
|
74
|
-
void Node256::
|
75
|
-
|
89
|
+
void Node256::DeleteChild(ART &art, Node &node, const uint8_t byte) {
|
90
|
+
|
91
|
+
D_ASSERT(node.IsSet());
|
92
|
+
D_ASSERT(!node.IsSwizzled());
|
93
|
+
auto &n256 = Node256::Get(art, node);
|
94
|
+
|
95
|
+
// free the child and decrease the count
|
96
|
+
Node::Free(art, n256.children[byte]);
|
97
|
+
n256.count--;
|
98
|
+
|
99
|
+
// shrink node to Node48
|
100
|
+
if (n256.count <= Node::NODE_256_SHRINK_THRESHOLD) {
|
101
|
+
auto node256 = node;
|
102
|
+
Node48::ShrinkNode256(art, node, node256);
|
103
|
+
}
|
76
104
|
}
|
77
105
|
|
78
|
-
|
79
|
-
|
106
|
+
optional_ptr<Node> Node256::GetNextChild(uint8_t &byte) {
|
107
|
+
|
108
|
+
for (idx_t i = byte; i < Node::NODE_256_CAPACITY; i++) {
|
109
|
+
if (children[i].IsSet()) {
|
110
|
+
byte = i;
|
111
|
+
return &children[i];
|
112
|
+
}
|
113
|
+
}
|
114
|
+
return nullptr;
|
80
115
|
}
|
81
116
|
|
82
|
-
|
83
|
-
|
117
|
+
BlockPointer Node256::Serialize(ART &art, MetaBlockWriter &writer) {
|
118
|
+
|
119
|
+
// recurse into children and retrieve child block pointers
|
120
|
+
vector<BlockPointer> child_block_pointers;
|
121
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
122
|
+
child_block_pointers.push_back(children[i].Serialize(art, writer));
|
123
|
+
}
|
124
|
+
|
125
|
+
// get pointer and write fields
|
126
|
+
auto block_pointer = writer.GetBlockPointer();
|
127
|
+
writer.Write(NType::NODE_256);
|
128
|
+
writer.Write<uint16_t>(count);
|
129
|
+
prefix.Serialize(art, writer);
|
84
130
|
|
85
|
-
|
86
|
-
|
131
|
+
// write child block pointers
|
132
|
+
for (auto &child_block_pointer : child_block_pointers) {
|
133
|
+
writer.Write(child_block_pointer.block_id);
|
134
|
+
writer.Write(child_block_pointer.offset);
|
135
|
+
}
|
136
|
+
|
137
|
+
return block_pointer;
|
87
138
|
}
|
88
139
|
|
89
|
-
void Node256::
|
90
|
-
|
140
|
+
void Node256::Deserialize(ART &art, MetaBlockReader &reader) {
|
141
|
+
|
142
|
+
count = reader.Read<uint16_t>();
|
143
|
+
prefix.Deserialize(art, reader);
|
91
144
|
|
92
|
-
//
|
93
|
-
|
94
|
-
|
95
|
-
art.DecreaseMemorySize(child->MemorySize(art, true));
|
145
|
+
// read child block pointers
|
146
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
147
|
+
children[i] = Node(reader);
|
96
148
|
}
|
149
|
+
}
|
97
150
|
|
98
|
-
|
99
|
-
n->children[pos].Reset();
|
100
|
-
n->count--;
|
151
|
+
void Node256::Vacuum(ART &art, const ARTFlags &flags) {
|
101
152
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
auto new_node = Node48::New();
|
106
|
-
art.IncreaseMemorySize(new_node->MemorySize(art, false));
|
107
|
-
new_node->prefix = std::move(n->prefix);
|
108
|
-
|
109
|
-
for (idx_t i = 0; i < Node256::GetSize(); i++) {
|
110
|
-
if (n->children[i]) {
|
111
|
-
new_node->child_index[i] = new_node->count;
|
112
|
-
new_node->children[new_node->count++] = n->children[i];
|
113
|
-
n->children[i] = nullptr;
|
114
|
-
}
|
153
|
+
for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
|
154
|
+
if (children[i].IsSet()) {
|
155
|
+
Node::Vacuum(art, children[i], flags);
|
115
156
|
}
|
116
|
-
|
117
|
-
art.DecreaseMemorySize(node->MemorySize(art, false));
|
118
|
-
Node::Delete(node);
|
119
|
-
node = new_node;
|
120
157
|
}
|
121
158
|
}
|
159
|
+
|
122
160
|
} // namespace duckdb
|