Repository: duckdb/duckdb
File: src/storage/table/scan_state.cpp (C++)

Code before:
	return root;
}

RowGroup *CustomOrderParallelCollectionScanState::GetNextRowGroup(const shared_ptr<RowGroupSegmentTree> &row_groups,
                                                                  RowGroup *row_group) {
	return ordered_row_groups[row_group];
}

Value CollectionScanStateHelper::RetrieveStat(const BaseStatistics &stats, OrderByStatistics order_by,
                                              OrderByColumnType column_type) {
	switch (order_by) {
	case OrderByStatistics::MIN:
		return column_type == OrderByColumnType::NUMERIC ? NumericStats::Min(stats) : StringStats::Min(stats);
	case OrderByStatistics::MAX:
		return column_type == OrderByColumnType::NUMERIC ? NumericStats::Max(stats) : StringStats::Max(stats);
	}
	return Value();
}

std::multimap<Value, RowGroup *> CollectionScanStateHelper::OrderRowGroups(RowGroupSegmentTree *row_groups,
                                                                           column_t column_idx,
                                                                           OrderByStatistics order_by,
                                                                           OrderByColumnType column_type) {
	std::multimap<Value, RowGroup *> ordered_row_groups;
	auto row_group = row_groups->GetRootSegment();
	while (row_group) {
		auto stats = row_group->GetStatistics(column_idx);
		Value comparison_value = RetrieveStat(*stats, order_by, column_type);
		ordered_row_groups.emplace(comparison_value, row_group);
		row_group = row_groups->GetNextSegment(row_group);
	}

	return ordered_row_groups;
}

unordered_map<RowGroup *, RowGroup *>
CollectionScanStateHelper::CreateRowGroupMap(const multimap<Value, RowGroup *> &row_groups,
                                             RowGroupOrderType order_type, RowGroup *&root) {
	if (row_groups.empty()) {
		return {};
	}

	unordered_map<RowGroup *, RowGroup *> row_group_map;

	RowGroup *current_row_group;
	if (order_type == RowGroupOrderType::ASC) {
		root = row_groups.begin()->second;
		current_row_group = root;
		for (auto it = std::next(row_groups.begin()); it != row_groups.end(); ++it) {
			row_group_map[current_row_group] = it->second;
			current_row_group = it->second;

Review comment (suggestion):
We can use this to iterate:
```cpp
for(auto &row_group : row_groups->Segments() {
}
```

Code after:
		}
	}
	D_ASSERT(!current || (row_index >= current->start && row_index < current->start + current->count));
}

void ColumnScanState::Next(idx_t count) {
	NextInternal(count);
	for (auto &child_state : child_states) {
		child_state.Next(count);
	}
}

const vector<StorageIndex> &CollectionScanState::GetColumnIds() {
	return parent.GetColumnIds();
}

TableFilterSet &GetFilters();

ScanFilterInfo &CollectionScanState::GetFilterInfo() {
	return parent.GetFilterInfo();
}

ScanSamplingInfo &CollectionScanState::GetSamplingInfo() {
	return parent.GetSamplingInfo();
}

TableScanOptions &CollectionScanState::GetOptions() {
	return parent.options;
}

ParallelCollectionScanState::ParallelCollectionScanState()
    : collection(nullptr), current_row_group(nullptr), processed_rows(0) {
}

optional_ptr<RowGroup> ParallelCollectionScanState::GetRootSegment(RowGroupSegmentTree &row_groups) const {
	if (reorderer) {
		return reorderer->GetRootSegment(row_groups);
	}
	return row_groups.GetRootSegment();
}

optional_ptr<RowGroup> ParallelCollectionScanState::GetNextRowGroup(RowGroupSegmentTree &row_groups,
                                                                    optional_ptr<RowGroup> row_group) const {
	if (reorderer) {
		return reorderer->GetNextRowGroup(row_group);
	}
	return row_groups.GetNextSegment(row_group.get());
}

CollectionScanState::CollectionScanState(TableScanState &parent_p)
    : row_group(nullptr), vector_index(0), max_row_group_row(0), row_groups(nullptr), max_row(0), batch_index(0),