duckdb 0.7.2-dev2507.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 (254) hide show
  1. package/binding.gyp +7 -7
  2. package/package.json +2 -2
  3. package/src/connection.cpp +1 -1
  4. package/src/duckdb/extension/icu/icu-dateadd.cpp +3 -3
  5. package/src/duckdb/extension/icu/icu-datepart.cpp +3 -3
  6. package/src/duckdb/extension/icu/icu-datesub.cpp +2 -2
  7. package/src/duckdb/extension/icu/icu-datetrunc.cpp +1 -1
  8. package/src/duckdb/extension/icu/icu-extension.cpp +3 -3
  9. package/src/duckdb/extension/icu/icu-list-range.cpp +2 -2
  10. package/src/duckdb/extension/icu/icu-makedate.cpp +1 -1
  11. package/src/duckdb/extension/icu/icu-strptime.cpp +4 -4
  12. package/src/duckdb/extension/icu/icu-table-range.cpp +2 -2
  13. package/src/duckdb/extension/icu/icu-timebucket.cpp +1 -1
  14. package/src/duckdb/extension/icu/icu-timezone.cpp +4 -4
  15. package/src/duckdb/extension/json/json-extension.cpp +6 -6
  16. package/src/duckdb/extension/parquet/parquet-extension.cpp +9 -8
  17. package/src/duckdb/extension/parquet/parquet_statistics.cpp +3 -0
  18. package/src/duckdb/src/catalog/catalog.cpp +166 -127
  19. package/src/duckdb/src/catalog/catalog_entry/copy_function_catalog_entry.cpp +3 -3
  20. package/src/duckdb/src/catalog/catalog_entry/duck_index_entry.cpp +1 -1
  21. package/src/duckdb/src/catalog/catalog_entry/duck_schema_entry.cpp +90 -82
  22. package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +65 -67
  23. package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +3 -3
  24. package/src/duckdb/src/catalog/catalog_entry/pragma_function_catalog_entry.cpp +4 -4
  25. package/src/duckdb/src/catalog/catalog_entry/scalar_function_catalog_entry.cpp +8 -8
  26. package/src/duckdb/src/catalog/catalog_entry/scalar_macro_catalog_entry.cpp +10 -10
  27. package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +6 -6
  28. package/src/duckdb/src/catalog/catalog_entry/sequence_catalog_entry.cpp +6 -6
  29. package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +4 -4
  30. package/src/duckdb/src/catalog/catalog_entry/table_function_catalog_entry.cpp +9 -9
  31. package/src/duckdb/src/catalog/catalog_entry/type_catalog_entry.cpp +5 -5
  32. package/src/duckdb/src/catalog/catalog_entry/view_catalog_entry.cpp +23 -23
  33. package/src/duckdb/src/catalog/catalog_entry.cpp +27 -6
  34. package/src/duckdb/src/catalog/catalog_search_path.cpp +2 -2
  35. package/src/duckdb/src/catalog/catalog_set.cpp +84 -87
  36. package/src/duckdb/src/catalog/catalog_transaction.cpp +1 -1
  37. package/src/duckdb/src/catalog/default/default_functions.cpp +1 -1
  38. package/src/duckdb/src/catalog/default/default_schemas.cpp +1 -1
  39. package/src/duckdb/src/catalog/default/default_types.cpp +1 -1
  40. package/src/duckdb/src/catalog/default/default_views.cpp +1 -1
  41. package/src/duckdb/src/catalog/dependency_list.cpp +2 -2
  42. package/src/duckdb/src/catalog/dependency_manager.cpp +9 -10
  43. package/src/duckdb/src/catalog/duck_catalog.cpp +30 -26
  44. package/src/duckdb/src/catalog/similar_catalog_entry.cpp +1 -1
  45. package/src/duckdb/src/common/radix_partitioning.cpp +1 -1
  46. package/src/duckdb/src/common/types.cpp +15 -27
  47. package/src/duckdb/src/execution/index/art/art.cpp +286 -269
  48. package/src/duckdb/src/execution/index/art/art_key.cpp +22 -32
  49. package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +224 -0
  50. package/src/duckdb/src/execution/index/art/iterator.cpp +142 -123
  51. package/src/duckdb/src/execution/index/art/leaf.cpp +319 -170
  52. package/src/duckdb/src/execution/index/art/leaf_segment.cpp +42 -0
  53. package/src/duckdb/src/execution/index/art/node.cpp +444 -379
  54. package/src/duckdb/src/execution/index/art/node16.cpp +178 -114
  55. package/src/duckdb/src/execution/index/art/node256.cpp +117 -79
  56. package/src/duckdb/src/execution/index/art/node4.cpp +169 -114
  57. package/src/duckdb/src/execution/index/art/node48.cpp +175 -105
  58. package/src/duckdb/src/execution/index/art/prefix.cpp +405 -127
  59. package/src/duckdb/src/execution/index/art/prefix_segment.cpp +42 -0
  60. package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +10 -85
  61. package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +4 -3
  62. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +2 -2
  63. package/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp +2 -0
  64. package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +4 -3
  65. package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +19 -18
  66. package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +5 -5
  67. package/src/duckdb/src/execution/operator/schema/physical_alter.cpp +1 -1
  68. package/src/duckdb/src/execution/operator/schema/physical_create_function.cpp +1 -1
  69. package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +17 -17
  70. package/src/duckdb/src/execution/operator/schema/physical_create_schema.cpp +1 -1
  71. package/src/duckdb/src/execution/operator/schema/physical_create_sequence.cpp +1 -1
  72. package/src/duckdb/src/execution/operator/schema/physical_create_table.cpp +2 -2
  73. package/src/duckdb/src/execution/operator/schema/physical_create_type.cpp +4 -3
  74. package/src/duckdb/src/execution/operator/schema/physical_create_view.cpp +1 -1
  75. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +1 -1
  76. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +2 -2
  77. package/src/duckdb/src/execution/physical_plan/plan_aggregate.cpp +1 -1
  78. package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +4 -4
  79. package/src/duckdb/src/execution/physical_plan/plan_create_table.cpp +4 -3
  80. package/src/duckdb/src/execution/physical_plan/plan_delete.cpp +1 -1
  81. package/src/duckdb/src/execution/physical_plan/plan_insert.cpp +1 -1
  82. package/src/duckdb/src/execution/physical_plan/plan_update.cpp +1 -1
  83. package/src/duckdb/src/function/built_in_functions.cpp +10 -10
  84. package/src/duckdb/src/function/function_binder.cpp +3 -3
  85. package/src/duckdb/src/function/scalar/list/list_aggregates.cpp +5 -6
  86. package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +2 -2
  87. package/src/duckdb/src/function/scalar/sequence/nextval.cpp +9 -8
  88. package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +6 -6
  89. package/src/duckdb/src/function/table/arrow.cpp +5 -5
  90. package/src/duckdb/src/function/table/read_csv.cpp +5 -1
  91. package/src/duckdb/src/function/table/system/duckdb_columns.cpp +8 -7
  92. package/src/duckdb/src/function/table/system/duckdb_constraints.cpp +14 -14
  93. package/src/duckdb/src/function/table/system/duckdb_databases.cpp +2 -2
  94. package/src/duckdb/src/function/table/system/duckdb_functions.cpp +26 -25
  95. package/src/duckdb/src/function/table/system/duckdb_indexes.cpp +13 -12
  96. package/src/duckdb/src/function/table/system/duckdb_schemas.cpp +7 -7
  97. package/src/duckdb/src/function/table/system/duckdb_sequences.cpp +8 -9
  98. package/src/duckdb/src/function/table/system/duckdb_tables.cpp +10 -9
  99. package/src/duckdb/src/function/table/system/duckdb_types.cpp +13 -13
  100. package/src/duckdb/src/function/table/system/duckdb_views.cpp +11 -10
  101. package/src/duckdb/src/function/table/system/pragma_collations.cpp +2 -2
  102. package/src/duckdb/src/function/table/system/pragma_database_size.cpp +5 -5
  103. package/src/duckdb/src/function/table/system/pragma_storage_info.cpp +3 -3
  104. package/src/duckdb/src/function/table/system/pragma_table_info.cpp +2 -2
  105. package/src/duckdb/src/function/table/table_scan.cpp +39 -37
  106. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  107. package/src/duckdb/src/function/udf_function.cpp +2 -2
  108. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +122 -81
  109. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp +2 -3
  110. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/collate_catalog_entry.hpp +3 -3
  111. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/copy_function_catalog_entry.hpp +1 -1
  112. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  113. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_schema_entry.hpp +24 -20
  114. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +3 -3
  115. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  116. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/macro_catalog_entry.hpp +2 -2
  117. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/pragma_function_catalog_entry.hpp +1 -1
  118. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/scalar_function_catalog_entry.hpp +2 -2
  119. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/scalar_macro_catalog_entry.hpp +1 -1
  120. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/schema_catalog_entry.hpp +22 -17
  121. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp +1 -1
  122. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_catalog_entry.hpp +1 -1
  123. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +2 -2
  124. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_macro_catalog_entry.hpp +1 -1
  125. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/type_catalog_entry.hpp +1 -1
  126. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/view_catalog_entry.hpp +3 -3
  127. package/src/duckdb/src/include/duckdb/catalog/catalog_entry.hpp +28 -7
  128. package/src/duckdb/src/include/duckdb/catalog/catalog_set.hpp +20 -19
  129. package/src/duckdb/src/include/duckdb/catalog/duck_catalog.hpp +9 -9
  130. package/src/duckdb/src/include/duckdb/catalog/similar_catalog_entry.hpp +2 -1
  131. package/src/duckdb/src/include/duckdb/catalog/standard_entry.hpp +10 -4
  132. package/src/duckdb/src/include/duckdb/common/enums/on_entry_not_found.hpp +17 -0
  133. package/src/duckdb/src/include/duckdb/common/queue.hpp +1 -1
  134. package/src/duckdb/src/include/duckdb/common/types.hpp +3 -4
  135. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +53 -45
  136. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +29 -24
  137. package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +114 -0
  138. package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +26 -20
  139. package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +63 -39
  140. package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +36 -0
  141. package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +98 -116
  142. package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +48 -36
  143. package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +52 -35
  144. package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +46 -36
  145. package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +57 -35
  146. package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +57 -50
  147. package/src/duckdb/src/include/duckdb/execution/index/art/prefix_segment.hpp +40 -0
  148. package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +38 -31
  149. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_file_handle.hpp +2 -1
  150. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  151. package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +4 -4
  152. package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +3 -2
  153. package/src/duckdb/src/include/duckdb/function/table/table_scan.hpp +5 -4
  154. package/src/duckdb/src/include/duckdb/function/table_function.hpp +28 -15
  155. package/src/duckdb/src/include/duckdb/main/attached_database.hpp +2 -0
  156. package/src/duckdb/src/include/duckdb/main/client_context.hpp +1 -1
  157. package/src/duckdb/src/include/duckdb/main/database_manager.hpp +3 -2
  158. package/src/duckdb/src/include/duckdb/parser/expression/bound_expression.hpp +2 -0
  159. package/src/duckdb/src/include/duckdb/parser/keyword_helper.hpp +2 -2
  160. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +7 -5
  161. package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp +1 -1
  162. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_info.hpp +1 -1
  163. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_view_info.hpp +1 -1
  164. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +3 -2
  165. package/src/duckdb/src/include/duckdb/parser/parsed_data/drop_info.hpp +5 -5
  166. package/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp +13 -0
  167. package/src/duckdb/src/include/duckdb/parser/statement/insert_statement.hpp +4 -1
  168. package/src/duckdb/src/include/duckdb/parser/tableref.hpp +5 -2
  169. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +4 -1
  170. package/src/duckdb/src/include/duckdb/planner/binder.hpp +2 -2
  171. package/src/duckdb/src/include/duckdb/planner/expression_binder/base_select_binder.hpp +1 -2
  172. package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +4 -7
  173. package/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp +1 -1
  174. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +0 -5
  175. package/src/duckdb/src/include/duckdb/storage/index.hpp +13 -28
  176. package/src/duckdb/src/include/duckdb/storage/standard_buffer_manager.hpp +0 -2
  177. package/src/duckdb/src/include/duckdb/transaction/cleanup_state.hpp +5 -0
  178. package/src/duckdb/src/include/duckdb/transaction/transaction.hpp +12 -0
  179. package/src/duckdb/src/include/duckdb.h +26 -0
  180. package/src/duckdb/src/main/attached_database.cpp +12 -6
  181. package/src/duckdb/src/main/capi/helper-c.cpp +7 -0
  182. package/src/duckdb/src/main/capi/table_function-c.cpp +17 -16
  183. package/src/duckdb/src/main/client_context.cpp +12 -11
  184. package/src/duckdb/src/main/database_manager.cpp +13 -12
  185. package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +1 -2
  186. package/src/duckdb/src/parser/parsed_data/alter_info.cpp +3 -3
  187. package/src/duckdb/src/parser/parsed_data/alter_scalar_function_info.cpp +2 -2
  188. package/src/duckdb/src/parser/parsed_data/alter_table_function_info.cpp +2 -2
  189. package/src/duckdb/src/parser/parsed_data/alter_table_info.cpp +9 -9
  190. package/src/duckdb/src/parser/parsed_data/create_scalar_function_info.cpp +2 -2
  191. package/src/duckdb/src/parser/parsed_data/create_table_function_info.cpp +2 -2
  192. package/src/duckdb/src/parser/parsed_data/create_table_info.cpp +2 -2
  193. package/src/duckdb/src/parser/parsed_data/create_view_info.cpp +2 -2
  194. package/src/duckdb/src/parser/statement/insert_statement.cpp +15 -6
  195. package/src/duckdb/src/parser/transform/constraint/transform_constraint.cpp +1 -1
  196. package/src/duckdb/src/parser/transform/expression/transform_function.cpp +18 -5
  197. package/src/duckdb/src/parser/transform/statement/transform_alter_sequence.cpp +3 -2
  198. package/src/duckdb/src/parser/transform/statement/transform_alter_table.cpp +5 -1
  199. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +1 -1
  200. package/src/duckdb/src/parser/transform/statement/transform_drop.cpp +1 -1
  201. package/src/duckdb/src/parser/transform/statement/transform_insert.cpp +5 -7
  202. package/src/duckdb/src/parser/transform/statement/transform_rename.cpp +1 -1
  203. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +26 -27
  204. package/src/duckdb/src/planner/binder/expression/bind_between_expression.cpp +17 -17
  205. package/src/duckdb/src/planner/binder/expression/bind_case_expression.cpp +9 -9
  206. package/src/duckdb/src/planner/binder/expression/bind_cast_expression.cpp +6 -6
  207. package/src/duckdb/src/planner/binder/expression/bind_collate_expression.cpp +6 -6
  208. package/src/duckdb/src/planner/binder/expression/bind_columnref_expression.cpp +2 -2
  209. package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +21 -21
  210. package/src/duckdb/src/planner/binder/expression/bind_conjunction_expression.cpp +2 -3
  211. package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +33 -36
  212. package/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp +5 -5
  213. package/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +23 -23
  214. package/src/duckdb/src/planner/binder/expression/bind_subquery_expression.cpp +4 -4
  215. package/src/duckdb/src/planner/binder/expression/bind_unnest_expression.cpp +7 -7
  216. package/src/duckdb/src/planner/binder/expression/bind_window_expression.cpp +23 -23
  217. package/src/duckdb/src/planner/binder/query_node/bind_table_macro_node.cpp +4 -4
  218. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +14 -13
  219. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +56 -42
  220. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +3 -3
  221. package/src/duckdb/src/planner/binder/statement/bind_delete.cpp +1 -1
  222. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +4 -4
  223. package/src/duckdb/src/planner/binder/statement/bind_export.cpp +10 -10
  224. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +16 -11
  225. package/src/duckdb/src/planner/binder/statement/bind_pragma.cpp +4 -4
  226. package/src/duckdb/src/planner/binder/statement/bind_simple.cpp +5 -4
  227. package/src/duckdb/src/planner/binder/statement/bind_update.cpp +1 -1
  228. package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +3 -3
  229. package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +10 -12
  230. package/src/duckdb/src/planner/binder.cpp +2 -2
  231. package/src/duckdb/src/planner/expression/bound_expression.cpp +11 -2
  232. package/src/duckdb/src/planner/operator/logical_copy_to_file.cpp +2 -5
  233. package/src/duckdb/src/planner/operator/logical_create.cpp +2 -1
  234. package/src/duckdb/src/planner/operator/logical_create_index.cpp +2 -2
  235. package/src/duckdb/src/planner/operator/logical_delete.cpp +2 -2
  236. package/src/duckdb/src/planner/operator/logical_get.cpp +1 -1
  237. package/src/duckdb/src/planner/operator/logical_insert.cpp +2 -7
  238. package/src/duckdb/src/planner/operator/logical_update.cpp +2 -6
  239. package/src/duckdb/src/planner/parsed_data/bound_create_table_info.cpp +2 -2
  240. package/src/duckdb/src/planner/pragma_handler.cpp +3 -4
  241. package/src/duckdb/src/storage/checkpoint_manager.cpp +57 -55
  242. package/src/duckdb/src/storage/data_table.cpp +9 -9
  243. package/src/duckdb/src/storage/index.cpp +18 -6
  244. package/src/duckdb/src/storage/local_storage.cpp +8 -2
  245. package/src/duckdb/src/storage/standard_buffer_manager.cpp +0 -9
  246. package/src/duckdb/src/storage/table/update_segment.cpp +1 -1
  247. package/src/duckdb/src/storage/wal_replay.cpp +29 -31
  248. package/src/duckdb/src/storage/write_ahead_log.cpp +8 -8
  249. package/src/duckdb/src/transaction/cleanup_state.cpp +7 -1
  250. package/src/duckdb/src/transaction/commit_state.cpp +3 -4
  251. package/src/duckdb/src/transaction/transaction_context.cpp +1 -1
  252. package/src/duckdb/src/transaction/undo_buffer.cpp +8 -0
  253. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  254. package/src/duckdb/ub_src_execution_index_art.cpp +7 -1
@@ -1,164 +1,219 @@
1
1
  #include "duckdb/execution/index/art/node4.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/node16.hpp"
5
6
  #include "duckdb/storage/meta_block_reader.hpp"
7
+ #include "duckdb/storage/meta_block_writer.hpp"
6
8
 
7
9
  namespace duckdb {
8
10
 
9
- Node4::Node4() : Node(NodeType::N4) {
10
- memset(key, 0, sizeof(key));
11
- }
11
+ Node4 &Node4::New(ART &art, Node &node) {
12
12
 
13
- idx_t Node4::MemorySize(ART &art, const bool &recurse) {
14
- if (recurse) {
15
- return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art);
16
- }
17
- return prefix.MemorySize() + sizeof(*this);
18
- }
13
+ node.SetPtr(Node::GetAllocator(art, NType::NODE_4).New());
14
+ node.type = (uint8_t)NType::NODE_4;
15
+ auto &n4 = Node4::Get(art, node);
19
16
 
20
- idx_t Node4::GetChildPos(uint8_t k) {
21
- for (idx_t pos = 0; pos < count; pos++) {
22
- if (key[pos] == k) {
23
- return pos;
24
- }
25
- }
26
- return Node::GetChildPos(k);
17
+ n4.count = 0;
18
+ n4.prefix.Initialize();
19
+ return n4;
27
20
  }
28
21
 
29
- idx_t Node4::GetChildGreaterEqual(uint8_t k, bool &equal) {
30
- for (idx_t pos = 0; pos < count; pos++) {
31
- if (key[pos] >= k) {
32
- if (key[pos] == k) {
33
- equal = true;
34
- } else {
35
- equal = false;
36
- }
37
- return pos;
38
- }
39
- }
40
- return DConstants::INVALID_INDEX;
41
- }
22
+ void Node4::Free(ART &art, Node &node) {
42
23
 
43
- idx_t Node4::GetMin() {
44
- return 0;
45
- }
24
+ D_ASSERT(node.IsSet());
25
+ D_ASSERT(!node.IsSwizzled());
26
+
27
+ auto &n4 = Node4::Get(art, node);
46
28
 
47
- idx_t Node4::GetNextPos(idx_t pos) {
48
- if (pos == DConstants::INVALID_INDEX) {
49
- return 0;
29
+ // free all children
30
+ for (idx_t i = 0; i < n4.count; i++) {
31
+ Node::Free(art, n4.children[i]);
50
32
  }
51
- pos++;
52
- return pos < count ? pos : DConstants::INVALID_INDEX;
53
33
  }
54
34
 
55
- idx_t Node4::GetNextPosAndByte(idx_t pos, uint8_t &byte) {
56
- if (pos == DConstants::INVALID_INDEX) {
57
- byte = key[0];
58
- return 0;
59
- }
60
- pos++;
61
- if (pos < count) {
62
- byte = key[pos];
63
- return pos;
35
+ Node4 &Node4::ShrinkNode16(ART &art, Node &node4, Node &node16) {
36
+
37
+ auto &n4 = Node4::New(art, node4);
38
+ auto &n16 = Node16::Get(art, node16);
39
+
40
+ n4.count = n16.count;
41
+ n4.prefix.Move(n16.prefix);
42
+
43
+ for (idx_t i = 0; i < n16.count; i++) {
44
+ n4.key[i] = n16.key[i];
45
+ n4.children[i] = n16.children[i];
64
46
  }
65
- return DConstants::INVALID_INDEX;
66
- }
67
47
 
68
- Node *Node4::GetChild(ART &art, idx_t pos) {
69
- D_ASSERT(pos < count);
70
- return children[pos].Unswizzle(art);
48
+ n16.count = 0;
49
+ Node::Free(art, node16);
50
+ return n4;
71
51
  }
72
52
 
73
- void Node4::ReplaceChildPointer(idx_t pos, Node *node) {
74
- children[pos] = node;
75
- }
53
+ void Node4::InitializeMerge(ART &art, const ARTFlags &flags) {
76
54
 
77
- bool Node4::ChildIsInMemory(idx_t pos) {
78
- return children[pos] && !children[pos].IsSwizzled();
55
+ for (idx_t i = 0; i < count; i++) {
56
+ children[i].InitializeMerge(art, flags);
57
+ }
79
58
  }
80
59
 
81
- void Node4::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) {
82
- Node4 *n = (Node4 *)node;
60
+ void Node4::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
61
+
62
+ D_ASSERT(node.IsSet());
63
+ D_ASSERT(!node.IsSwizzled());
64
+ auto &n4 = Node4::Get(art, node);
65
+
66
+ // ensure that there is no other child at the same byte
67
+ for (idx_t i = 0; i < n4.count; i++) {
68
+ D_ASSERT(n4.key[i] != byte);
69
+ }
83
70
 
84
71
  // insert new child node into node
85
- if (node->count < Node4::GetSize()) {
72
+ if (n4.count < Node::NODE_4_CAPACITY) {
86
73
  // still space, just insert the child
87
- idx_t pos = 0;
88
- while ((pos < node->count) && (n->key[pos] < key_byte)) {
89
- pos++;
74
+ idx_t child_pos = 0;
75
+ while (child_pos < n4.count && n4.key[child_pos] < byte) {
76
+ child_pos++;
90
77
  }
91
- if (n->children[pos]) {
92
- for (idx_t i = n->count; i > pos; i--) {
93
- n->key[i] = n->key[i - 1];
94
- n->children[i] = n->children[i - 1];
95
- }
78
+ // move children backwards to make space
79
+ for (idx_t i = n4.count; i > child_pos; i--) {
80
+ n4.key[i] = n4.key[i - 1];
81
+ n4.children[i] = n4.children[i - 1];
96
82
  }
97
- n->key[pos] = key_byte;
98
- n->children[pos] = new_child;
99
- n->count++;
83
+
84
+ n4.key[child_pos] = byte;
85
+ n4.children[child_pos] = child;
86
+ n4.count++;
100
87
 
101
88
  } else {
102
89
  // node is full, grow to Node16
103
- auto new_node = Node16::New();
104
- art.IncreaseMemorySize(new_node->MemorySize(art, false));
105
- new_node->count = n->count;
106
- new_node->prefix = std::move(node->prefix);
107
-
108
- for (idx_t i = 0; i < n->count; i++) {
109
- new_node->key[i] = n->key[i];
110
- new_node->children[i] = n->children[i];
111
- n->children[i] = nullptr;
112
- }
113
- n->count = 0;
114
-
115
- art.DecreaseMemorySize(node->MemorySize(art, false));
116
- Node::Delete(node);
117
- node = new_node;
118
- Node16::InsertChild(art, node, key_byte, new_child);
90
+ auto node4 = node;
91
+ Node16::GrowNode4(art, node, node4);
92
+ Node16::InsertChild(art, node, byte, child);
119
93
  }
120
94
  }
121
95
 
122
- void Node4::EraseChild(ART &art, Node *&node, idx_t pos) {
96
+ void Node4::DeleteChild(ART &art, Node &node, const uint8_t byte) {
123
97
 
124
- Node4 *n = (Node4 *)node;
125
- D_ASSERT(pos < n->count);
126
- D_ASSERT(n->count > 1);
98
+ D_ASSERT(node.IsSet());
99
+ D_ASSERT(!node.IsSwizzled());
100
+ auto &n4 = Node4::Get(art, node);
127
101
 
128
- // adjust the ART size
129
- if (n->ChildIsInMemory(pos)) {
130
- auto child = n->GetChild(art, pos);
131
- art.DecreaseMemorySize(child->MemorySize(art, true));
102
+ idx_t child_pos = 0;
103
+ for (; child_pos < n4.count; child_pos++) {
104
+ if (n4.key[child_pos] == byte) {
105
+ break;
106
+ }
132
107
  }
133
108
 
134
- // erase the child and decrease the count
135
- n->children[pos].Reset();
136
- n->count--;
137
- D_ASSERT(n->count >= 1);
109
+ D_ASSERT(child_pos < n4.count);
110
+ D_ASSERT(n4.count > 1);
111
+
112
+ // free the child and decrease the count
113
+ Node::Free(art, n4.children[child_pos]);
114
+ n4.count--;
138
115
 
139
116
  // 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];
143
- }
144
- // set any remaining nodes as nullptr
145
- for (; pos < Node4::GetSize(); pos++) {
146
- n->children[pos] = nullptr;
117
+ for (idx_t i = child_pos; i < n4.count; i++) {
118
+ n4.key[i] = n4.key[i + 1];
119
+ n4.children[i] = n4.children[i + 1];
147
120
  }
148
121
 
149
122
  // this is a one way node, compress
150
- if (n->count == 1) {
123
+ if (n4.count == 1) {
151
124
 
152
125
  // get only child and concatenate prefixes
153
- auto child_ref = n->GetChild(art, 0);
154
- // concatenate prefixes
155
- child_ref->prefix.Concatenate(art, n->key[0], node->prefix);
156
- // ensure that when deleting the node, we do not delete the child (because we move it)
157
- n->children[0] = nullptr;
126
+ auto child = *n4.GetChild(n4.key[0]);
127
+ child.GetPrefix(art).Concatenate(art, n4.key[0], n4.prefix);
128
+ n4.count--;
129
+
130
+ Node::Free(art, node);
131
+ node = child;
132
+ }
133
+ }
158
134
 
159
- art.DecreaseMemorySize(n->MemorySize(art, false));
160
- Node::Delete(node);
161
- node = child_ref;
135
+ void Node4::ReplaceChild(const uint8_t byte, const Node child) {
136
+ for (idx_t i = 0; i < count; i++) {
137
+ if (key[i] == byte) {
138
+ children[i] = child;
139
+ return;
140
+ }
162
141
  }
163
142
  }
143
+
144
+ optional_ptr<Node> Node4::GetChild(const uint8_t byte) {
145
+
146
+ for (idx_t i = 0; i < count; i++) {
147
+ if (key[i] == byte) {
148
+ return &children[i];
149
+ }
150
+ }
151
+ return nullptr;
152
+ }
153
+
154
+ optional_ptr<Node> Node4::GetNextChild(uint8_t &byte) {
155
+
156
+ for (idx_t i = 0; i < count; i++) {
157
+ if (key[i] >= byte) {
158
+ byte = key[i];
159
+ return &children[i];
160
+ }
161
+ }
162
+ return nullptr;
163
+ }
164
+
165
+ BlockPointer Node4::Serialize(ART &art, MetaBlockWriter &writer) {
166
+
167
+ // recurse into children and retrieve child block pointers
168
+ vector<BlockPointer> child_block_pointers;
169
+ for (idx_t i = 0; i < count; i++) {
170
+ child_block_pointers.push_back(children[i].Serialize(art, writer));
171
+ }
172
+ for (idx_t i = count; i < Node::NODE_4_CAPACITY; i++) {
173
+ child_block_pointers.emplace_back((block_id_t)DConstants::INVALID_INDEX, 0);
174
+ }
175
+
176
+ // get pointer and write fields
177
+ auto block_pointer = writer.GetBlockPointer();
178
+ writer.Write(NType::NODE_4);
179
+ writer.Write<uint8_t>(count);
180
+ prefix.Serialize(art, writer);
181
+
182
+ // write key values
183
+ for (idx_t i = 0; i < Node::NODE_4_CAPACITY; i++) {
184
+ writer.Write(key[i]);
185
+ }
186
+
187
+ // write child block pointers
188
+ for (auto &child_block_pointer : child_block_pointers) {
189
+ writer.Write(child_block_pointer.block_id);
190
+ writer.Write(child_block_pointer.offset);
191
+ }
192
+
193
+ return block_pointer;
194
+ }
195
+
196
+ void Node4::Deserialize(ART &art, MetaBlockReader &reader) {
197
+
198
+ count = reader.Read<uint8_t>();
199
+ prefix.Deserialize(art, reader);
200
+
201
+ // read key values
202
+ for (idx_t i = 0; i < Node::NODE_4_CAPACITY; i++) {
203
+ key[i] = reader.Read<uint8_t>();
204
+ }
205
+
206
+ // read child block pointers
207
+ for (idx_t i = 0; i < Node::NODE_4_CAPACITY; i++) {
208
+ children[i] = Node(reader);
209
+ }
210
+ }
211
+
212
+ void Node4::Vacuum(ART &art, const ARTFlags &flags) {
213
+
214
+ for (idx_t i = 0; i < count; i++) {
215
+ Node::Vacuum(art, children[i], flags);
216
+ }
217
+ }
218
+
164
219
  } // namespace duckdb
@@ -1,160 +1,230 @@
1
1
  #include "duckdb/execution/index/art/node48.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/node16.hpp"
5
6
  #include "duckdb/execution/index/art/node256.hpp"
7
+ #include "duckdb/storage/meta_block_reader.hpp"
8
+ #include "duckdb/storage/meta_block_writer.hpp"
6
9
 
7
10
  namespace duckdb {
8
11
 
9
- Node48::Node48() : Node(NodeType::N48) {
10
- for (idx_t i = 0; i < 256; i++) {
11
- child_index[i] = Node::EMPTY_MARKER;
12
+ Node48 &Node48::New(ART &art, Node &node) {
13
+
14
+ node.SetPtr(Node::GetAllocator(art, NType::NODE_48).New());
15
+ node.type = (uint8_t)NType::NODE_48;
16
+ auto &n48 = Node48::Get(art, node);
17
+
18
+ n48.count = 0;
19
+ n48.prefix.Initialize();
20
+
21
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
22
+ n48.child_index[i] = Node::EMPTY_MARKER;
12
23
  }
13
- }
14
24
 
15
- idx_t Node48::MemorySize(ART &art, const bool &recurse) {
16
- if (recurse) {
17
- return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art);
25
+ // necessary for faster child insertion/deletion
26
+ for (idx_t i = 0; i < Node::NODE_48_CAPACITY; i++) {
27
+ n48.children[i].Reset();
18
28
  }
19
- return prefix.MemorySize() + sizeof(*this);
29
+
30
+ return n48;
20
31
  }
21
32
 
22
- idx_t Node48::GetChildPos(uint8_t k) {
23
- if (child_index[k] == Node::EMPTY_MARKER) {
24
- return DConstants::INVALID_INDEX;
25
- } else {
26
- return k;
33
+ void Node48::Free(ART &art, Node &node) {
34
+
35
+ D_ASSERT(node.IsSet());
36
+ D_ASSERT(!node.IsSwizzled());
37
+
38
+ auto &n48 = Node48::Get(art, node);
39
+
40
+ if (!n48.count) {
41
+ return;
27
42
  }
28
- }
29
43
 
30
- idx_t Node48::GetChildGreaterEqual(uint8_t k, bool &equal) {
31
- for (idx_t pos = k; pos < Node256::GetSize(); pos++) {
32
- if (child_index[pos] != Node::EMPTY_MARKER) {
33
- if (pos == k) {
34
- equal = true;
35
- } else {
36
- equal = false;
37
- }
38
- return pos;
44
+ // free all children
45
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
46
+ if (n48.child_index[i] != Node::EMPTY_MARKER) {
47
+ Node::Free(art, n48.children[n48.child_index[i]]);
39
48
  }
40
49
  }
41
- return DConstants::INVALID_INDEX;
42
50
  }
43
51
 
44
- idx_t Node48::GetMin() {
45
- for (idx_t i = 0; i < Node256::GetSize(); i++) {
46
- if (child_index[i] != Node::EMPTY_MARKER) {
47
- return i;
48
- }
52
+ Node48 &Node48::GrowNode16(ART &art, Node &node48, Node &node16) {
53
+
54
+ auto &n16 = Node16::Get(art, node16);
55
+ auto &n48 = Node48::New(art, node48);
56
+
57
+ n48.count = n16.count;
58
+ n48.prefix.Move(n16.prefix);
59
+
60
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
61
+ n48.child_index[i] = Node::EMPTY_MARKER;
49
62
  }
50
- return DConstants::INVALID_INDEX;
51
- }
52
63
 
53
- idx_t Node48::GetNextPos(idx_t pos) {
54
- pos == DConstants::INVALID_INDEX ? pos = 0 : pos++;
55
- for (; pos < Node256::GetSize(); pos++) {
56
- if (child_index[pos] != Node::EMPTY_MARKER) {
57
- return pos;
58
- }
64
+ for (idx_t i = 0; i < n16.count; i++) {
65
+ n48.child_index[n16.key[i]] = i;
66
+ n48.children[i] = n16.children[i];
67
+ }
68
+
69
+ // necessary for faster child insertion/deletion
70
+ for (idx_t i = n16.count; i < Node::NODE_48_CAPACITY; i++) {
71
+ n48.children[i].Reset();
59
72
  }
60
- return Node::GetNextPos(pos);
73
+
74
+ n16.count = 0;
75
+ Node::Free(art, node16);
76
+ return n48;
61
77
  }
62
78
 
63
- idx_t Node48::GetNextPosAndByte(idx_t pos, uint8_t &byte) {
64
- pos == DConstants::INVALID_INDEX ? pos = 0 : pos++;
65
- for (; pos < Node256::GetSize(); pos++) {
66
- if (child_index[pos] != Node::EMPTY_MARKER) {
67
- byte = uint8_t(pos);
68
- return pos;
79
+ Node48 &Node48::ShrinkNode256(ART &art, Node &node48, Node &node256) {
80
+
81
+ auto &n48 = Node48::New(art, node48);
82
+ auto &n256 = Node256::Get(art, node256);
83
+
84
+ n48.count = 0;
85
+ n48.prefix.Move(n256.prefix);
86
+
87
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
88
+ if (n256.children[i].IsSet()) {
89
+ n48.child_index[i] = n48.count;
90
+ n48.children[n48.count] = n256.children[i];
91
+ n48.count++;
92
+ } else {
93
+ n48.child_index[i] = Node::EMPTY_MARKER;
69
94
  }
70
95
  }
71
- return Node::GetNextPos(pos);
72
- }
73
96
 
74
- Node *Node48::GetChild(ART &art, idx_t pos) {
75
- D_ASSERT(child_index[pos] != Node::EMPTY_MARKER);
76
- return children[child_index[pos]].Unswizzle(art);
77
- }
97
+ // necessary for faster child insertion/deletion
98
+ for (idx_t i = n48.count; i < Node::NODE_48_CAPACITY; i++) {
99
+ n48.children[i].Reset();
100
+ }
78
101
 
79
- void Node48::ReplaceChildPointer(idx_t pos, Node *node) {
80
- children[child_index[pos]] = node;
102
+ n256.count = 0;
103
+ Node::Free(art, node256);
104
+ return n48;
81
105
  }
82
106
 
83
- bool Node48::ChildIsInMemory(idx_t pos) {
84
- return children[child_index[pos]] && !children[child_index[pos]].IsSwizzled();
107
+ void Node48::InitializeMerge(ART &art, const ARTFlags &flags) {
108
+
109
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
110
+ if (child_index[i] != Node::EMPTY_MARKER) {
111
+ children[child_index[i]].InitializeMerge(art, flags);
112
+ }
113
+ }
85
114
  }
86
115
 
87
- void Node48::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) {
88
- auto n = (Node48 *)node;
116
+ void Node48::InsertChild(ART &art, Node &node, const uint8_t byte, const Node child) {
117
+
118
+ D_ASSERT(node.IsSet());
119
+ D_ASSERT(!node.IsSwizzled());
120
+ auto &n48 = Node48::Get(art, node);
121
+
122
+ // ensure that there is no other child at the same byte
123
+ D_ASSERT(n48.child_index[byte] == Node::EMPTY_MARKER);
89
124
 
90
125
  // insert new child node into node
91
- if (node->count < Node48::GetSize()) {
126
+ if (n48.count < Node::NODE_48_CAPACITY) {
92
127
  // still space, just insert the child
93
- idx_t pos = n->count;
94
- if (n->children[pos]) {
128
+ idx_t child_pos = n48.count;
129
+ if (n48.children[child_pos].IsSet()) {
95
130
  // find an empty position in the node list if the current position is occupied
96
- pos = 0;
97
- while (n->children[pos]) {
98
- pos++;
131
+ child_pos = 0;
132
+ while (n48.children[child_pos].IsSet()) {
133
+ child_pos++;
99
134
  }
100
135
  }
101
- n->children[pos] = new_child;
102
- n->child_index[key_byte] = pos;
103
- n->count++;
136
+ n48.children[child_pos] = child;
137
+ n48.child_index[byte] = child_pos;
138
+ n48.count++;
104
139
 
105
140
  } else {
106
141
  // node is full, grow to Node256
107
- auto new_node = Node256::New();
108
- art.IncreaseMemorySize(new_node->MemorySize(art, false));
109
- new_node->count = n->count;
110
- new_node->prefix = std::move(n->prefix);
111
-
112
- for (idx_t i = 0; i < Node256::GetSize(); i++) {
113
- if (n->child_index[i] != Node::EMPTY_MARKER) {
114
- new_node->children[i] = n->children[n->child_index[i]];
115
- n->children[n->child_index[i]] = nullptr;
116
- }
117
- }
118
-
119
- art.DecreaseMemorySize(node->MemorySize(art, false));
120
- Node::Delete(node);
121
- node = new_node;
122
- Node256::InsertChild(art, node, key_byte, new_child);
142
+ auto node48 = node;
143
+ Node256::GrowNode48(art, node, node48);
144
+ Node256::InsertChild(art, node, byte, child);
123
145
  }
124
146
  }
125
147
 
126
- void Node48::EraseChild(ART &art, Node *&node, idx_t pos) {
127
- auto n = (Node48 *)(node);
148
+ void Node48::DeleteChild(ART &art, Node &node, const uint8_t byte) {
128
149
 
129
- // adjust the ART size
130
- if (n->ChildIsInMemory(pos)) {
131
- auto child = n->GetChild(art, pos);
132
- art.DecreaseMemorySize(child->MemorySize(art, true));
133
- }
150
+ D_ASSERT(node.IsSet());
151
+ D_ASSERT(!node.IsSwizzled());
152
+ auto &n48 = Node48::Get(art, node);
134
153
 
135
- // erase the child and decrease the count
136
- n->children[n->child_index[pos]].Reset();
137
- n->child_index[pos] = Node::EMPTY_MARKER;
138
- n->count--;
154
+ // free the child and decrease the count
155
+ Node::Free(art, n48.children[n48.child_index[byte]]);
156
+ n48.child_index[byte] = Node::EMPTY_MARKER;
157
+ n48.count--;
139
158
 
140
159
  // shrink node to Node16
141
- if (node->count < NODE_48_SHRINK_THRESHOLD) {
160
+ if (n48.count < Node::NODE_48_SHRINK_THRESHOLD) {
161
+ auto node48 = node;
162
+ Node16::ShrinkNode48(art, node, node48);
163
+ }
164
+ }
142
165
 
143
- auto new_node = Node16::New();
144
- art.IncreaseMemorySize(new_node->MemorySize(art, false));
145
- new_node->prefix = std::move(n->prefix);
166
+ optional_ptr<Node> Node48::GetNextChild(uint8_t &byte) {
146
167
 
147
- for (idx_t i = 0; i < Node256::GetSize(); i++) {
148
- if (n->child_index[i] != Node::EMPTY_MARKER) {
149
- new_node->key[new_node->count] = i;
150
- new_node->children[new_node->count++] = n->children[n->child_index[i]];
151
- n->children[n->child_index[i]] = nullptr;
152
- }
168
+ for (idx_t i = byte; i < Node::NODE_256_CAPACITY; i++) {
169
+ if (child_index[i] != Node::EMPTY_MARKER) {
170
+ byte = i;
171
+ return &children[child_index[i]];
153
172
  }
173
+ }
174
+ return nullptr;
175
+ }
176
+
177
+ BlockPointer Node48::Serialize(ART &art, MetaBlockWriter &writer) {
178
+
179
+ // recurse into children and retrieve child block pointers
180
+ vector<BlockPointer> child_block_pointers;
181
+ for (idx_t i = 0; i < Node::NODE_48_CAPACITY; i++) {
182
+ child_block_pointers.push_back(children[i].Serialize(art, writer));
183
+ }
184
+
185
+ // get pointer and write fields
186
+ auto block_pointer = writer.GetBlockPointer();
187
+ writer.Write(NType::NODE_48);
188
+ writer.Write<uint8_t>(count);
189
+ prefix.Serialize(art, writer);
190
+
191
+ // write key values
192
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
193
+ writer.Write(child_index[i]);
194
+ }
195
+
196
+ // write child block pointers
197
+ for (auto &child_block_pointer : child_block_pointers) {
198
+ writer.Write(child_block_pointer.block_id);
199
+ writer.Write(child_block_pointer.offset);
200
+ }
201
+
202
+ return block_pointer;
203
+ }
204
+
205
+ void Node48::Deserialize(ART &art, MetaBlockReader &reader) {
206
+
207
+ count = reader.Read<uint8_t>();
208
+ prefix.Deserialize(art, reader);
209
+
210
+ // read key values
211
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
212
+ child_index[i] = reader.Read<uint8_t>();
213
+ }
214
+
215
+ // read child block pointers
216
+ for (idx_t i = 0; i < Node::NODE_48_CAPACITY; i++) {
217
+ children[i] = Node(reader);
218
+ }
219
+ }
154
220
 
155
- art.DecreaseMemorySize(node->MemorySize(art, false));
156
- Node::Delete(node);
157
- node = new_node;
221
+ void Node48::Vacuum(ART &art, const ARTFlags &flags) {
222
+
223
+ for (idx_t i = 0; i < Node::NODE_256_CAPACITY; i++) {
224
+ if (child_index[i] != Node::EMPTY_MARKER) {
225
+ Node::Vacuum(art, children[child_index[i]], flags);
226
+ }
158
227
  }
159
228
  }
229
+
160
230
  } // namespace duckdb