Repository: duckdb/duckdb
File: src/include/duckdb/execution/index/art/iterator.hpp (C++)

Code before:
		return key_bytes[idx];
	}
	// Returns the number of key bytes.
	inline idx_t Size() const {
		return key_bytes.size();
	}
	//! Returns a pointer to the key bytes.
	inline const_data_ptr_t Data() const {
		return const_data_ptr_cast(key_bytes.data());
	}

	//! Returns true, if key_bytes contains all bytes of key.
	bool Contains(const ARTKey &key) const;
	//! Returns true, if key_bytes is greater than [or equal to] the key.
	bool GreaterThan(const ARTKey &key, const bool equal, const uint8_t nested_depth) const;

private:
	unsafe_vector<uint8_t> key_bytes;
};

//===--------------------------------------------------------------------===//
// Scan Output Policies
//===--------------------------------------------------------------------===//

//! Output policy for scanning row IDs only into a set.
struct RowIdSetOutput {
	set<row_t> &row_ids;

	explicit RowIdSetOutput(set<row_t> &row_ids) : row_ids(row_ids) {
	}

	bool IsFull(idx_t max_count) const {
#ifdef DEBUG
		D_ASSERT(row_ids.size() >= 0 && row_ids.size() <= max_count);
#endif
		return row_ids.size() >= max_count;
	}
	void SetKey(const IteratorKey &, idx_t) {
		// No-op: we don't need keys for row ID output.
	}
	void Emit(row_t rid) {
		row_ids.insert(rid);
	}
};

//! Output policy for scanning keys and row IDs into vectors.
struct KeyRowIdVectorOutput {
	ArenaAllocator &arena;
	unsafe_vector<ARTKey> &keys;
	unsafe_vector<ARTKey> &row_id_keys;
	idx_t count = 0;

Review comment (suggestion):
Let's pass `max_count` to the constructor for both `RowIdSetOutput` and `KeyRowIdVectorOutput`. Both can have a field `capacity`. Then, we do not need to propagate `max_output` into the `Iterator` scan functions anymore and we can just call `output.IsFull()`.

Code after:
		return key_bytes[idx];
	}
	// Returns the number of key bytes.
	inline idx_t Size() const {
		return key_bytes.size();
	}
	//! Returns a pointer to the key bytes.
	inline const_data_ptr_t Data() const {
		return const_data_ptr_cast(key_bytes.data());
	}

	//! Returns true, if key_bytes contains all bytes of key.
	bool Contains(const ARTKey &key) const;
	//! Returns true, if key_bytes is greater than [or equal to] the key.
	bool GreaterThan(const ARTKey &key, const bool equal, const uint8_t nested_depth) const;

private:
	unsafe_vector<uint8_t> key_bytes;
};

//===--------------------------------------------------------------------===//
// Scan Output Policies
//===--------------------------------------------------------------------===//

//! Output policy for scanning row IDs only into a set.
struct RowIdSetOutput {
	set<row_t> &row_ids;
	const idx_t capacity;

	RowIdSetOutput(set<row_t> &row_ids, const idx_t capacity) : row_ids(row_ids), capacity(capacity) {
	}

	bool IsFull() const {
		D_ASSERT(row_ids.size() >= 0 && row_ids.size() <= capacity);
		return row_ids.size() >= capacity;
	}
	void SetKey(const IteratorKey &, const idx_t) {
		// No-op: we don't need keys for row ID output.
	}
	void Add(const row_t rid) {
		row_ids.insert(rid);
	}
};

//! Output policy for scanning keys and row IDs.
struct KeyRowIdOutput {
	ArenaAllocator &arena;
	unsafe_vector<ARTKey> &keys;
	unsafe_vector<ARTKey> &row_id_keys;
	const idx_t capacity;
	idx_t count = 0;