File indexing completed on 2025-12-16 09:23:03
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/EventData/SpacePointContainer2.hpp"
0010
0011 #include "Acts/Utilities/Helpers.hpp"
0012
0013 #include <string_view>
0014 #include <unordered_set>
0015
0016 namespace {
0017
0018 template <typename Tuple>
0019 using tuple_indices =
0020 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>;
0021
0022 }
0023
0024 namespace Acts {
0025
0026 static_assert(std::random_access_iterator<SpacePointContainer2::iterator>);
0027 static_assert(
0028 std::random_access_iterator<SpacePointContainer2::const_iterator>);
0029 static_assert(
0030 std::random_access_iterator<SpacePointContainer2::MutableSubset::Iterator>);
0031 static_assert(
0032 std::random_access_iterator<SpacePointContainer2::ConstSubset::Iterator>);
0033
0034 SpacePointContainer2::SpacePointContainer2(SpacePointColumns columns) noexcept {
0035 createColumns(columns);
0036 }
0037
0038 SpacePointContainer2::SpacePointContainer2(
0039 const SpacePointContainer2 &other) noexcept
0040 : m_size(other.m_size), m_sourceLinks(other.m_sourceLinks) {
0041 copyColumns(other);
0042 }
0043
0044 SpacePointContainer2::SpacePointContainer2(
0045 SpacePointContainer2 &&other) noexcept
0046 : m_size(other.m_size), m_sourceLinks(std::move(other.m_sourceLinks)) {
0047 moveColumns(other);
0048
0049 other.m_size = 0;
0050 }
0051
0052 SpacePointContainer2 &SpacePointContainer2::operator=(
0053 const SpacePointContainer2 &other) noexcept {
0054 if (this == &other) {
0055 return *this;
0056 }
0057
0058 m_size = other.m_size;
0059 m_sourceLinks = other.m_sourceLinks;
0060 copyColumns(other);
0061
0062 return *this;
0063 }
0064
0065 SpacePointContainer2 &SpacePointContainer2::operator=(
0066 SpacePointContainer2 &&other) noexcept {
0067 if (this == &other) {
0068 return *this;
0069 }
0070
0071 m_size = other.m_size;
0072 m_sourceLinks = std::move(other.m_sourceLinks);
0073 moveColumns(other);
0074
0075 other.m_size = 0;
0076
0077 return *this;
0078 }
0079
0080 void SpacePointContainer2::copyColumns(const SpacePointContainer2 &other) {
0081 m_namedColumns.reserve(other.m_namedColumns.size());
0082
0083 for (const auto &[name, column] : other.m_namedColumns) {
0084 std::unique_ptr<ColumnHolderBase> holder =
0085 column.second != nullptr ? column.second->copy() : nullptr;
0086 m_namedColumns.try_emplace(name,
0087 std::pair{holder.get(), std::move(holder)});
0088 }
0089
0090 m_knownColumns = other.m_knownColumns;
0091 knownColumns() = other.knownColumns();
0092 }
0093
0094 void SpacePointContainer2::moveColumns(SpacePointContainer2 &other) noexcept {
0095 m_namedColumns.reserve(other.m_namedColumns.size());
0096
0097 for (auto &[name, column] : other.m_namedColumns) {
0098 m_namedColumns.try_emplace(name, std::move(column));
0099 }
0100
0101 other.m_namedColumns.clear();
0102
0103 m_knownColumns = other.m_knownColumns;
0104 knownColumns() = std::move(other).knownColumns();
0105 }
0106
0107 void SpacePointContainer2::reserve(std::uint32_t size,
0108 float averageSourceLinks) noexcept {
0109 if (hasColumns(SpacePointColumns::SourceLinks)) {
0110 m_sourceLinks.reserve(
0111 static_cast<std::uint32_t>(size * averageSourceLinks));
0112 }
0113
0114 for (const auto &[name, column] : m_namedColumns) {
0115 column.first->reserve(size);
0116 }
0117 }
0118
0119 void SpacePointContainer2::clear() noexcept {
0120 m_size = 0;
0121 m_sourceLinks.clear();
0122
0123 for (const auto &[name, column] : m_namedColumns) {
0124 column.first->clear();
0125 }
0126 }
0127
0128 MutableSpacePointProxy2 SpacePointContainer2::createSpacePoint() noexcept {
0129 ++m_size;
0130
0131 for (const auto &[name, column] : m_namedColumns) {
0132 column.first->emplace_back();
0133 }
0134
0135 return MutableProxy(*this, size() - 1);
0136 }
0137
0138 void SpacePointContainer2::assignSourceLinks(
0139 Index index, std::span<const SourceLink> sourceLinks) {
0140 if (index >= size()) {
0141 throw std::out_of_range("Index out of range in SpacePointContainer2");
0142 }
0143 if (!m_sourceLinkOffsetColumn.has_value() ||
0144 !m_sourceLinkCountColumn.has_value()) {
0145 throw std::logic_error("No source links column available");
0146 }
0147 if (m_sourceLinkCountColumn->proxy(*this)[index] != 0) {
0148 throw std::logic_error("Source links already assigned to the space point");
0149 }
0150
0151 m_sourceLinkOffsetColumn->proxy(*this)[index] =
0152 static_cast<SpacePointIndex2>(m_sourceLinks.size());
0153 m_sourceLinkCountColumn->proxy(*this)[index] =
0154 static_cast<std::uint8_t>(sourceLinks.size());
0155 m_sourceLinks.insert(m_sourceLinks.end(), sourceLinks.begin(),
0156 sourceLinks.end());
0157 }
0158
0159 void SpacePointContainer2::createColumns(SpacePointColumns columns) noexcept {
0160 using enum SpacePointColumns;
0161
0162 const auto createColumn =
0163 [&]<typename T>(SpacePointColumns mask, std::string_view name,
0164 T defaultValue, std::optional<ColumnHolder<T>> &column) {
0165 if (ACTS_CHECK_BIT(columns, mask) && !column.has_value()) {
0166 column = ColumnHolder<T>(std::move(defaultValue));
0167 column->resize(size());
0168 m_namedColumns.try_emplace(std::string(name),
0169 std::pair{&column.value(), nullptr});
0170 m_knownColumns = m_knownColumns | mask;
0171 }
0172 };
0173
0174 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0175 ((createColumn(
0176 std::get<Is>(knownColumnMasks()), std::get<Is>(knownColumnNames()),
0177 std::get<Is>(knownColumnDefaults()), std::get<Is>(knownColumns()))),
0178 ...);
0179 }(tuple_indices<decltype(knownColumns())>{});
0180 }
0181
0182 void SpacePointContainer2::dropColumns(SpacePointColumns columns) noexcept {
0183 using enum SpacePointColumns;
0184
0185 const auto dropColumn = [&]<typename T>(
0186 SpacePointColumns mask, std::string_view name,
0187 std::optional<ColumnHolder<T>> &column) {
0188 if (ACTS_CHECK_BIT(columns, mask) && column.has_value()) {
0189 m_namedColumns.erase(std::string(name));
0190 column.reset();
0191 m_knownColumns = m_knownColumns & ~mask;
0192 }
0193 };
0194
0195 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
0196 ((dropColumn(std::get<Is>(knownColumnMasks()),
0197 std::get<Is>(knownColumnNames()),
0198 std::get<Is>(knownColumns()))),
0199 ...);
0200 }(tuple_indices<decltype(knownColumns())>{});
0201
0202 if (ACTS_CHECK_BIT(columns, SpacePointColumns::SourceLinks)) {
0203 m_sourceLinks.clear();
0204 }
0205 }
0206
0207 void SpacePointContainer2::dropColumn(const std::string &name) {
0208 if (reservedColumn(name)) {
0209 throw std::runtime_error("Cannot drop reserved column: " + name);
0210 }
0211
0212 auto it = m_namedColumns.find(name);
0213 if (it == m_namedColumns.end()) {
0214 throw std::runtime_error("Column does not exist: " + name);
0215 }
0216
0217 m_namedColumns.erase(it);
0218 }
0219
0220 bool SpacePointContainer2::reservedColumn(const std::string &name) noexcept {
0221 static const auto reservedColumns = std::apply(
0222 [](auto... reservedNames) {
0223 return std::unordered_set<std::string, std::hash<std::string_view>,
0224 std::equal_to<>>({reservedNames...});
0225 },
0226 knownColumnNames());
0227
0228 return reservedColumns.contains(name);
0229 }
0230
0231 }