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.
Files changed (66) hide show
  1. package/binding.gyp +7 -7
  2. package/package.json +2 -2
  3. package/src/duckdb/extension/parquet/parquet_statistics.cpp +3 -0
  4. package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +2 -2
  5. package/src/duckdb/src/common/radix_partitioning.cpp +1 -1
  6. package/src/duckdb/src/execution/index/art/art.cpp +286 -269
  7. package/src/duckdb/src/execution/index/art/art_key.cpp +22 -32
  8. package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +224 -0
  9. package/src/duckdb/src/execution/index/art/iterator.cpp +142 -123
  10. package/src/duckdb/src/execution/index/art/leaf.cpp +319 -170
  11. package/src/duckdb/src/execution/index/art/leaf_segment.cpp +42 -0
  12. package/src/duckdb/src/execution/index/art/node.cpp +444 -379
  13. package/src/duckdb/src/execution/index/art/node16.cpp +178 -114
  14. package/src/duckdb/src/execution/index/art/node256.cpp +117 -79
  15. package/src/duckdb/src/execution/index/art/node4.cpp +169 -114
  16. package/src/duckdb/src/execution/index/art/node48.cpp +175 -105
  17. package/src/duckdb/src/execution/index/art/prefix.cpp +405 -127
  18. package/src/duckdb/src/execution/index/art/prefix_segment.cpp +42 -0
  19. package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +10 -85
  20. package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +2 -1
  21. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +2 -2
  22. package/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp +2 -0
  23. package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +11 -12
  24. package/src/duckdb/src/function/table/read_csv.cpp +5 -1
  25. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  26. package/src/duckdb/src/include/duckdb/common/queue.hpp +1 -1
  27. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +53 -45
  28. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +29 -24
  29. package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +114 -0
  30. package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +26 -20
  31. package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +63 -39
  32. package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +36 -0
  33. package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +98 -116
  34. package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +48 -36
  35. package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +52 -35
  36. package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +46 -36
  37. package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +57 -35
  38. package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +57 -50
  39. package/src/duckdb/src/include/duckdb/execution/index/art/prefix_segment.hpp +40 -0
  40. package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +38 -31
  41. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_file_handle.hpp +2 -1
  42. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  43. package/src/duckdb/src/include/duckdb/parser/statement/insert_statement.hpp +4 -1
  44. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +2 -1
  45. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +0 -5
  46. package/src/duckdb/src/include/duckdb/storage/index.hpp +13 -28
  47. package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +0 -2
  48. package/src/duckdb/src/include/duckdb/transaction/cleanup_state.hpp +5 -0
  49. package/src/duckdb/src/include/duckdb.h +26 -0
  50. package/src/duckdb/src/main/capi/helper-c.cpp +7 -0
  51. package/src/duckdb/src/parser/statement/insert_statement.cpp +15 -6
  52. package/src/duckdb/src/parser/transform/constraint/transform_constraint.cpp +1 -1
  53. package/src/duckdb/src/parser/transform/expression/transform_function.cpp +18 -5
  54. package/src/duckdb/src/parser/transform/statement/transform_insert.cpp +5 -7
  55. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +20 -7
  56. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +14 -9
  57. package/src/duckdb/src/storage/checkpoint_manager.cpp +11 -9
  58. package/src/duckdb/src/storage/data_table.cpp +6 -3
  59. package/src/duckdb/src/storage/index.cpp +18 -6
  60. package/src/duckdb/src/storage/local_storage.cpp +8 -2
  61. package/src/duckdb/src/storage/standard_buffer_manager.cpp +0 -9
  62. package/src/duckdb/src/storage/wal_replay.cpp +1 -1
  63. package/src/duckdb/src/transaction/cleanup_state.cpp +6 -0
  64. package/src/duckdb/src/transaction/undo_buffer.cpp +8 -0
  65. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  66. 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 <cstring>
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::Node16() : Node(NodeType::N16) {
12
- memset(key, 16, sizeof(key));
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
- idx_t Node16::MemorySize(ART &art, const bool &recurse) {
16
- if (recurse) {
17
- return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art);
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
- idx_t Node16::GetChildPos(uint8_t k) {
23
- for (idx_t pos = 0; pos < count; pos++) {
24
- if (key[pos] == k) {
25
- return pos;
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
- return Node::GetChildPos(k);
48
+
49
+ n4.count = 0;
50
+ Node::Free(art, node4);
51
+ return n16;
29
52
  }
30
53
 
31
- idx_t Node16::GetChildGreaterEqual(uint8_t k, bool &equal) {
32
- for (idx_t pos = 0; pos < count; pos++) {
33
- if (key[pos] >= k) {
34
- if (key[pos] == k) {
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
- return pos;
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
- idx_t Node16::GetMin() {
47
- return 0;
70
+ n48.count = 0;
71
+ Node::Free(art, node48);
72
+ return n16;
48
73
  }
49
74
 
50
- idx_t Node16::GetNextPos(idx_t pos) {
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
- idx_t Node16::GetNextPosAndByte(idx_t pos, uint8_t &byte) {
59
- if (pos == DConstants::INVALID_INDEX) {
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::ReplaceChildPointer(idx_t pos, Node *node) {
77
- children[pos] = node;
78
- }
82
+ void Node16::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
79
83
 
80
- bool Node16::ChildIsInMemory(idx_t pos) {
81
- return children[pos] && !children[pos].IsSwizzled();
82
- }
84
+ D_ASSERT(node.IsSet());
85
+ D_ASSERT(!node.IsSwizzled());
86
+ auto &n16 = Node16::Get(art, node);
83
87
 
84
- void Node16::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) {
85
- Node16 *n = (Node16 *)node;
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 (n->count < Node16::GetSize()) {
94
+ if (n16.count < Node::NODE_16_CAPACITY) {
89
95
  // still space, just insert the child
90
- idx_t pos = 0;
91
- while (pos < node->count && n->key[pos] < key_byte) {
92
- pos++;
96
+ idx_t child_pos = 0;
97
+ while (child_pos < n16.count && n16.key[child_pos] < byte) {
98
+ child_pos++;
93
99
  }
94
- if (n->children[pos]) {
95
- for (idx_t i = n->count; i > pos; i--) {
96
- n->key[i] = n->key[i - 1];
97
- n->children[i] = n->children[i - 1];
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
- n->key[pos] = key_byte;
101
- n->children[pos] = new_child;
102
- n->count++;
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 new_node = Node48::New();
107
- art.IncreaseMemorySize(new_node->MemorySize(art, false));
108
- new_node->count = node->count;
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::EraseChild(ART &art, Node *&node, idx_t pos) {
118
+ void Node16::DeleteChild(ART &art, Node &node, const uint8_t byte) {
125
119
 
126
- auto n = (Node16 *)node;
127
- D_ASSERT(pos < n->count);
120
+ D_ASSERT(node.IsSet());
121
+ D_ASSERT(!node.IsSwizzled());
122
+ auto &n16 = Node16::Get(art, node);
128
123
 
129
- // adjust the ART size
130
- if (n->ChildIsInMemory(pos)) {
131
- auto child = n->GetChild(art, pos);
132
- art.DecreaseMemorySize(child->MemorySize(art, true));
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
- // erase the child and decrease the count
136
- n->children[pos].Reset();
137
- n->count--;
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 (; pos < n->count; pos++) {
141
- n->key[pos] = n->key[pos + 1];
142
- n->children[pos] = n->children[pos + 1];
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
- // set any remaining nodes as nullptr
145
- for (; pos < Node16::GetSize(); pos++) {
146
- if (!n->children[pos]) {
147
- break;
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
- // shrink node to Node4
153
- if (node->count < Node4::GetSize()) {
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
- auto new_node = Node4::New();
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
- for (idx_t i = 0; i < n->count; i++) {
160
- new_node->key[new_node->count] = n->key[i];
161
- new_node->children[new_node->count++] = n->children[i];
162
- n->children[i] = nullptr;
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
- art.DecreaseMemorySize(node->MemorySize(art, false));
166
- Node::Delete(node);
167
- node = new_node;
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::Node256() : Node(NodeType::N256) {
9
- }
11
+ Node256 &Node256::New(ART &art, Node &node) {
10
12
 
11
- idx_t Node256::MemorySize(ART &art, const bool &recurse) {
12
- if (recurse) {
13
- return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art);
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
- idx_t Node256::GetChildPos(uint8_t k) {
19
- if (children[k]) {
20
- return k;
21
- } else {
22
- return DConstants::INVALID_INDEX;
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
- idx_t Node256::GetChildGreaterEqual(uint8_t k, bool &equal) {
27
- for (idx_t pos = k; pos < Node256::GetSize(); pos++) {
28
- if (children[pos]) {
29
- if (pos == k) {
30
- equal = true;
31
- } else {
32
- equal = false;
33
- }
34
- return pos;
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
- idx_t Node256::GetMin() {
41
- for (idx_t i = 0; i < Node256::GetSize(); i++) {
42
- if (children[i]) {
43
- return i;
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
- idx_t Node256::GetNextPos(idx_t pos) {
50
- pos == DConstants::INVALID_INDEX ? pos = 0 : pos++;
51
- for (; pos < Node256::GetSize(); pos++) {
52
- if (children[pos]) {
53
- return pos;
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
- return Node::GetNextPos(pos);
61
+
62
+ n48.count = 0;
63
+ Node::Free(art, node48);
64
+ return n256;
57
65
  }
58
66
 
59
- idx_t Node256::GetNextPosAndByte(idx_t pos, uint8_t &byte) {
60
- pos == DConstants::INVALID_INDEX ? pos = 0 : pos++;
61
- for (; pos < Node256::GetSize(); pos++) {
62
- if (children[pos]) {
63
- byte = uint8_t(pos);
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
- Node *Node256::GetChild(ART &art, idx_t pos) {
71
- return children[pos].Unswizzle(art);
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::ReplaceChildPointer(idx_t pos, Node *node) {
75
- children[pos] = node;
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
- bool Node256::ChildIsInMemory(idx_t pos) {
79
- return children[pos] && !children[pos].IsSwizzled();
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
- void Node256::InsertChild(ART &, Node *&node, uint8_t key_byte, Node *new_child) {
83
- auto n = (Node256 *)(node);
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
- n->count++;
86
- n->children[key_byte] = new_child;
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::EraseChild(ART &art, Node *&node, idx_t pos) {
90
- auto n = (Node256 *)(node);
140
+ void Node256::Deserialize(ART &art, MetaBlockReader &reader) {
141
+
142
+ count = reader.Read<uint16_t>();
143
+ prefix.Deserialize(art, reader);
91
144
 
92
- // adjust the ART size
93
- if (n->ChildIsInMemory(pos)) {
94
- auto child = n->GetChild(art, pos);
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
- // erase the child and decrease the count
99
- n->children[pos].Reset();
100
- n->count--;
151
+ void Node256::Vacuum(ART &art, const ARTFlags &flags) {
101
152
 
102
- // shrink node to Node48
103
- if (node->count <= NODE_256_SHRINK_THRESHOLD) {
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