CbmRoot
Loading...
Searching...
No Matches
PartitionedVector.h
Go to the documentation of this file.
1/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Felix Weiglhofer [committer] */
4#ifndef CBM_ALGO_BASE_PARTITIONED_VECTOR_H
5#define CBM_ALGO_BASE_PARTITIONED_VECTOR_H
6
7#include "Definitions.h"
8#include "util/PODAllocator.h"
9
10#include <boost/serialization/access.hpp>
11#include <boost/serialization/vector.hpp>
12
13#include <gsl/span>
14#include <vector>
15
16namespace cbm::algo
17{
18 template<typename T>
20
29 template<typename T, class Allocator = std::allocator<T>>
31
32 public:
33 using Container_t = std::vector<T, Allocator>; //< Underlying container type
34
39
49 PartitionedVector(Container_t&& data, gsl::span<const size_t> sizes, gsl::span<const u32> addresses)
50 : fData(std::move(data))
51 , fOffsets()
52 , fAdresses(addresses.begin(), addresses.end())
53 {
54 ComputeOffsets(sizes);
56 }
57
61 template<typename OtherAllocator>
63 : fData(other.Data().begin(), other.Data().end())
64 , fOffsets(other.Offsets())
65 , fAdresses(other.Addresses())
66 {
67 // TODO: this check is overkill? We already know that the dimensions are correct,
68 // since they were already checked in the other vector
70 }
71
72 template<typename U>
74 : fData(other.Data().begin(), other.Data().end())
75 , fOffsets(other.Offsets().begin(), other.Offsets().end())
76 , fAdresses(other.Addresses().begin(), other.Addresses().end())
77 {
79 }
80
84 gsl::span<T> operator[](size_t i)
85 {
86 EnsureBounds(i);
87 return UnsafePartitionSpan(i);
88 }
89
93 gsl::span<const T> operator[](size_t i) const
94 {
95 EnsureBounds(i);
96 return UnsafePartitionSpan(i);
97 }
98
102 u32 Address(size_t i) const
103 {
104 EnsureBounds(i);
105 return fAdresses[i];
106 }
107
111 std::pair<gsl::span<T>, u32> Partition(size_t i)
112 {
113 EnsureBounds(i);
114 return std::pair<gsl::span<T>, u32>(UnsafePartitionSpan(i), fAdresses[i]);
115 }
116
120 std::pair<gsl::span<const T>, u32> Partition(size_t i) const
121 {
122 EnsureBounds(i);
123 return std::pair<gsl::span<const T>, u32>(UnsafePartitionSpan(i), fAdresses[i]);
124 }
125
129 size_t NPartitions() const { return fAdresses.size(); }
130
134 size_t Size(size_t i) const
135 {
136 EnsureBounds(i);
137 return UnsafeSize(i);
138 }
139
143 size_t NElements() const { return fData.size(); }
144
148 size_t SizeBytes() const { return fData.size() * sizeof(T); }
149
153 gsl::span<T> Data() { return fData; }
154
158 gsl::span<const T> Data() const { return fData; }
159
163 const std::vector<u32>& Addresses() const { return fAdresses; }
164
168 const std::vector<size_t>& Offsets() const { return fOffsets; }
169
170 private:
172 std::vector<size_t> fOffsets; // < Offsets of the partitions in fData
173 std::vector<u32> fAdresses; //< Hardware addresses of the partitions
174
175 void EnsureDimensions() const
176 {
177 if (fOffsets.size() - 1 != fAdresses.size()) {
178 throw std::runtime_error("PartitionedVector: fOffsets.size() != fAdresses.size()");
179 }
180 if (fOffsets.front() != 0) {
181 throw std::runtime_error("PartitionedVector: fOffsets.front() != 0");
182 }
183 if (fOffsets.back() != fData.size()) {
184 throw std::runtime_error("PartitionedVector: fOffsets.back() != fData.size()");
185 }
186 }
187
188 void EnsureBounds(size_t i) const
189 {
190 if (i >= fAdresses.size()) throw std::out_of_range("PartitionedVector: index out of bounds");
191 }
192
193 void ComputeOffsets(gsl::span<const size_t> sizes)
194 {
195 fOffsets.reserve(sizes.size() + 1);
196 fOffsets.push_back(0);
197 for (auto n : sizes) {
198 fOffsets.push_back(fOffsets.back() + n);
199 }
200 }
201
202 size_t UnsafeSize(size_t i) const { return fOffsets[i + 1] - fOffsets[i]; }
203
204 gsl::span<T> UnsafePartitionSpan(size_t i) { return gsl::span<T>(fData.data() + fOffsets[i], UnsafeSize(i)); }
205
206 gsl::span<const T> UnsafePartitionSpan(size_t i) const
207 {
208 return gsl::span<const T>(fData.data() + fOffsets[i], UnsafeSize(i));
209 }
210
211 private: // serialization
213
214 template<class Archive>
215 void serialize(Archive& ar, unsigned int /*version*/)
216 {
217 ar& fData;
218 ar& fOffsets;
219 ar& fAdresses;
220 }
221 };
222
223 template<typename T>
225
226} // namespace cbm::algo
227
228#endif
A vector that is partitioned into multiple subvectors.
void ComputeOffsets(gsl::span< const size_t > sizes)
size_t SizeBytes() const
Return total size in bytes of the underlying data.
const std::vector< u32 > & Addresses() const
Get the addresses.
void serialize(Archive &ar, unsigned int)
std::pair< gsl::span< const T >, u32 > Partition(size_t i) const
Get a pair of the data and the hardware address of partition i.
std::vector< size_t > fOffsets
PartitionedVector(PartitionedSpan< U > other)
gsl::span< const T > Data() const
Get the underlying data.
gsl::span< T > UnsafePartitionSpan(size_t i)
std::pair< gsl::span< T >, u32 > Partition(size_t i)
Get a pair of the data and the hardware address of partition i.
size_t Size(size_t i) const
Get the size of partition i.
gsl::span< T > operator[](size_t i)
Access data at partition i.
size_t UnsafeSize(size_t i) const
std::vector< T, Allocator > Container_t
PartitionedVector(Container_t &&data, gsl::span< const size_t > sizes, gsl::span< const u32 > addresses)
Constructor. Creates a vector with n partitions.
PartitionedVector()
Default constructor. Creates an empty vector.
gsl::span< T > Data()
Get the underlying data.
const std::vector< size_t > & Offsets() const
Get the underlying offsets.
size_t NElements() const
Get the total number of elements in the container across all partitions.
friend class boost::serialization::access
size_t NPartitions() const
Get the number of partitions.
gsl::span< const T > UnsafePartitionSpan(size_t i) const
u32 Address(size_t i) const
Get the hardware address of partition i.
gsl::span< const T > operator[](size_t i) const
Access data at partition i.
void EnsureBounds(size_t i) const
PartitionedVector(const PartitionedVector< T, OtherAllocator > &other)
Copy constructor. Copy the data from other vector.
std::uint32_t u32
Definition Definitions.h:21
Hash for CbmL1LinkKey.