|
7 | 7 | #include "duckdb/execution/index/art/base_leaf.hpp"
|
8 | 8 | #include "duckdb/execution/index/art/base_node.hpp"
|
9 | 9 | #include "duckdb/execution/index/art/iterator.hpp"
|
| 10 | +#include "duckdb/execution/index/art/art_scanner.hpp" |
10 | 11 | #include "duckdb/execution/index/art/leaf.hpp"
|
11 | 12 | #include "duckdb/execution/index/art/node256.hpp"
|
12 | 13 | #include "duckdb/execution/index/art/node256_leaf.hpp"
|
@@ -362,35 +363,23 @@ bool Node::IsAnyLeaf() const {
|
362 | 363 |
|
363 | 364 | void Node::InitMerge(ART &art, const unsafe_vector<idx_t> &upper_bounds) {
|
364 | 365 | D_ASSERT(HasMetadata());
|
365 |
| - auto type = GetType(); |
| 366 | + ARTScanner<ARTScanHandlingMode::POP> scanner(art); |
366 | 367 |
|
367 |
| - switch (type) { |
368 |
| - case NType::PREFIX: |
369 |
| - return Prefix::InitializeMerge(art, *this, upper_bounds); |
370 |
| - case NType::LEAF: |
371 |
| - throw InternalException("Failed to initialize merge due to deprecated ART storage."); |
372 |
| - case NType::NODE_4: |
373 |
| - InitMergeInternal(art, Ref<Node4>(art, *this, type), upper_bounds); |
374 |
| - break; |
375 |
| - case NType::NODE_16: |
376 |
| - InitMergeInternal(art, Ref<Node16>(art, *this, type), upper_bounds); |
377 |
| - break; |
378 |
| - case NType::NODE_48: |
379 |
| - InitMergeInternal(art, Ref<Node48>(art, *this, type), upper_bounds); |
380 |
| - break; |
381 |
| - case NType::NODE_256: |
382 |
| - InitMergeInternal(art, Ref<Node256>(art, *this, type), upper_bounds); |
383 |
| - break; |
384 |
| - case NType::LEAF_INLINED: |
385 |
| - return; |
386 |
| - case NType::NODE_7_LEAF: |
387 |
| - case NType::NODE_15_LEAF: |
388 |
| - case NType::NODE_256_LEAF: |
389 |
| - break; |
390 |
| - } |
| 368 | + auto handler = [&upper_bounds](Node &node) { |
| 369 | + auto type = node.GetType(); |
| 370 | + if (node.GetType() == NType::LEAF_INLINED) { |
| 371 | + return ARTScanResult::CONTINUE; |
| 372 | + } |
| 373 | + if (type == NType::LEAF) { |
| 374 | + throw InternalException("deprecated ART storage in InitMerge"); |
| 375 | + } |
| 376 | + auto idx = GetAllocatorIdx(type); |
| 377 | + node.IncreaseBufferId(upper_bounds[idx]); |
| 378 | + return ARTScanResult::CONTINUE; |
| 379 | + }; |
391 | 380 |
|
392 |
| - auto idx = GetAllocatorIdx(type); |
393 |
| - IncreaseBufferId(upper_bounds[idx]); |
| 381 | + scanner.Init(handler, *this); |
| 382 | + scanner.Scan(handler); |
394 | 383 | }
|
395 | 384 |
|
396 | 385 | bool Node::MergeNormalNodes(ART &art, Node &l_node, Node &r_node, uint8_t &byte, const GateStatus status) {
|
@@ -597,48 +586,45 @@ bool Node::MergeInternal(ART &art, Node &other, const GateStatus status) {
|
597 | 586 |
|
598 | 587 | void Node::Vacuum(ART &art, const unordered_set<uint8_t> &indexes) {
|
599 | 588 | D_ASSERT(HasMetadata());
|
600 |
| - |
601 |
| - auto type = GetType(); |
602 |
| - switch (type) { |
603 |
| - case NType::LEAF_INLINED: |
604 |
| - return; |
605 |
| - case NType::PREFIX: |
606 |
| - return Prefix::Vacuum(art, *this, indexes); |
607 |
| - case NType::LEAF: |
608 |
| - if (indexes.find(GetAllocatorIdx(type)) == indexes.end()) { |
609 |
| - return; |
| 589 | + ARTScanner<ARTScanHandlingMode::EMPLACE> scanner(art); |
| 590 | + |
| 591 | + auto handler = [&art, &indexes](Node &node) { |
| 592 | + ARTScanResult result; |
| 593 | + auto type = node.GetType(); |
| 594 | + switch (type) { |
| 595 | + case NType::LEAF_INLINED: |
| 596 | + return ARTScanResult::SKIP; |
| 597 | + case NType::LEAF: { |
| 598 | + if (indexes.find(GetAllocatorIdx(type)) == indexes.end()) { |
| 599 | + return ARTScanResult::SKIP; |
| 600 | + } |
| 601 | + Leaf::DeprecatedVacuum(art, node); |
| 602 | + return ARTScanResult::SKIP; |
| 603 | + } |
| 604 | + case NType::NODE_7_LEAF: |
| 605 | + case NType::NODE_15_LEAF: |
| 606 | + case NType::NODE_256_LEAF: |
| 607 | + result = ARTScanResult::SKIP; |
| 608 | + break; |
| 609 | + default: |
| 610 | + result = ARTScanResult::CONTINUE; |
| 611 | + break; |
610 | 612 | }
|
611 |
| - return Leaf::DeprecatedVacuum(art, *this); |
612 |
| - default: |
613 |
| - break; |
614 |
| - } |
615 | 613 |
|
616 |
| - auto idx = GetAllocatorIdx(type); |
617 |
| - auto &allocator = GetAllocator(art, type); |
618 |
| - auto needs_vacuum = indexes.find(idx) != indexes.end() && allocator.NeedsVacuum(*this); |
619 |
| - if (needs_vacuum) { |
620 |
| - auto status = GetGateStatus(); |
621 |
| - *this = allocator.VacuumPointer(*this); |
622 |
| - SetMetadata(static_cast<uint8_t>(type)); |
623 |
| - SetGateStatus(status); |
624 |
| - } |
| 614 | + auto idx = GetAllocatorIdx(type); |
| 615 | + auto &allocator = GetAllocator(art, type); |
| 616 | + auto needs_vacuum = indexes.find(idx) != indexes.end() && allocator.NeedsVacuum(node); |
| 617 | + if (needs_vacuum) { |
| 618 | + auto status = node.GetGateStatus(); |
| 619 | + node = allocator.VacuumPointer(node); |
| 620 | + node.SetMetadata(static_cast<uint8_t>(type)); |
| 621 | + node.SetGateStatus(status); |
| 622 | + } |
| 623 | + return result; |
| 624 | + }; |
625 | 625 |
|
626 |
| - switch (type) { |
627 |
| - case NType::NODE_4: |
628 |
| - return VacuumInternal(art, Ref<Node4>(art, *this, type), indexes); |
629 |
| - case NType::NODE_16: |
630 |
| - return VacuumInternal(art, Ref<Node16>(art, *this, type), indexes); |
631 |
| - case NType::NODE_48: |
632 |
| - return VacuumInternal(art, Ref<Node48>(art, *this, type), indexes); |
633 |
| - case NType::NODE_256: |
634 |
| - return VacuumInternal(art, Ref<Node256>(art, *this, type), indexes); |
635 |
| - case NType::NODE_7_LEAF: |
636 |
| - case NType::NODE_15_LEAF: |
637 |
| - case NType::NODE_256_LEAF: |
638 |
| - return; |
639 |
| - default: |
640 |
| - throw InternalException("Invalid node type for Vacuum: %s.", EnumUtil::ToString(type)); |
641 |
| - } |
| 626 | + scanner.Init(handler, *this); |
| 627 | + scanner.Scan(handler); |
642 | 628 | }
|
643 | 629 |
|
644 | 630 | //===--------------------------------------------------------------------===//
|
|
0 commit comments