#include <ankerl/unordered_dense.h> // Assuming this is the include for ankerl::unordered_dense
#include <optional>
#include <string_view>
#include <cstddef>
// Assuming StringPool, internal::check, ErrorCode, TRACE, and log::version are defined elsewhere.
class ColumnMap {
ankerl::unordered_dense::map<std::string_view, size_t> column_offsets_;
StringPool pool_;
public:
ColumnMap(size_t size) : column_offsets_(size) {}
void insert(std::string_view name, size_t index) {
// Check for duplicate name to prevent accidental overwrites
if (column_offsets_.contains(name)) {
internal::check<ErrorCode::E_INVALID_ARGUMENT>(
false,
"Column with name '{}' already exists",
name
);
}
auto off_str = pool_.get(name);
auto view = pool_.getView(off_str.offset());
column_offsets_[view] = index; // Use operator[] for insertion
}
void erase(std::string_view name) {
auto it = column_offsets_.find(name);
internal::check<ErrorCode::E_INVALID_ARGUMENT>(
it != column_offsets_.end(),
"Cannot drop column with name '{}' as it doesn't exist",
name
);
auto dropped_offset = it->second;
column_offsets_.erase(it);
// Shift offsets greater than dropped_offset
for (auto& [_, offset] : column_offsets_) {
if (offset > dropped_offset) {
--offset;
}
}
}
std::optional<size_t> column_index(std::string_view name) const {
auto it = column_offsets_.find(name);
if (it != column_offsets_.end()) {
return it->second;
} else {
TRACE(
log::version(),
"Column {} not found in map of size {}",
name, column_offsets_.size()
);
return std::nullopt;
}
}
// Optional additions for robustness (comment out if not needed)
size_t size() const {
return column_offsets_.size();
}
// Validate that indices are dense (0 to size()-1) with no duplicates or gaps
void validate_indices() const {
std::unordered_set<size_t> seen;
for (const auto& [_, offset] : column_offsets_) {
internal::check<ErrorCode::E_INTERNAL>(
offset < column_offsets_.size() && seen.insert(offset).second,
"Invalid column indices: duplicates or gaps detected"
);
}
}
};