TTK
Loading...
Searching...
No Matches
FlatJaggedArray.h
Go to the documentation of this file.
1#pragma once
2
3#include <Debug.h>
4
5namespace ttk {
13 // flattened sub-vectors data
14 std::vector<SimplexId> data_;
15 // offset for every sub-vector
16 std::vector<SimplexId> offsets_;
17
18 public:
19 // ############## //
20 // Initialization //
21 // ############## //
22
26 inline void setData(std::vector<SimplexId> &&data,
27 std::vector<SimplexId> &&offsets) {
28 this->data_ = std::move(data);
29 this->offsets_ = std::move(offsets);
30 }
31
35 inline void clear() {
36 this->data_.clear();
37 this->offsets_.clear();
38 }
39
40 // ############################## //
41 // Mimic the vector of vector API //
42 // ############################## //
43
47 inline SimplexId size(SimplexId id) const {
48#ifndef TTK_ENABLE_KAMIKAZE
49 if(id < 0 || id > (SimplexId)offsets_.size() - 1) {
50 return -1;
51 }
52#endif
53 return this->offsets_[id + 1] - this->offsets_[id];
54 }
55
59 inline SimplexId offset(SimplexId id) const {
60#ifndef TTK_ENABLE_KAMIKAZE
61 if(id < 0 || id > (SimplexId)offsets_.size()) {
62 return -1;
63 }
64#endif
65 return this->offsets_[id];
66 }
67
68 struct Slice {
69 const size_t len;
70 const SimplexId *const ptr;
71 inline SimplexId operator[](const size_t id) const {
72#ifndef TTK_ENABLE_KAMIKAZE
73 if(id >= this->len || ptr == nullptr) {
74 return -1;
75 }
76#endif
77 return this->ptr[id];
78 }
79 inline const SimplexId *data() const {
80 return this->ptr;
81 }
82 inline const SimplexId *begin() const {
83 return this->ptr;
84 }
85 inline const SimplexId *end() const {
86 return this->ptr + this->len;
87 }
88 inline size_t size() const {
89 return this->len;
90 }
91 };
92
93 struct Iterator {
94 size_t id;
96 inline void operator++() {
97 this->id++;
98 }
99 inline Slice operator*() const {
100 return this->parent[this->id];
101 }
102 inline bool operator!=(const Iterator &other) const {
103 return this->id != other.id;
104 }
105 };
106
107 inline Iterator begin() const {
108 return {0, *this};
109 }
110 inline Iterator end() const {
111 return {this->size(), *this};
112 }
113
114 inline Slice operator[](const size_t id) const {
115#ifndef TTK_ENABLE_KAMIKAZE
116 if(id >= this->offsets_.size()) {
117 return {0, nullptr};
118 }
119#endif
120 return {static_cast<size_t>(this->size(id)), this->get_ptr(id, 0)};
121 }
122
126 inline SimplexId get(SimplexId id, SimplexId local) const {
127#ifndef TTK_ENABLE_KAMIKAZE
128 if(id < 0 || id > (SimplexId)offsets_.size() - 1) {
129 return -1;
130 }
131 if(local < 0 || local >= this->size(id)) {
132 return -2;
133 }
134#endif
135 return this->data_[this->offsets_[id] + local];
136 }
137
141 inline const SimplexId *get_ptr(SimplexId id, SimplexId local) const {
142#ifndef TTK_ENABLE_KAMIKAZE
143 if(id < 0 || id > (SimplexId)offsets_.size() - 1) {
144 return {};
145 }
146 if(local < 0 || local >= this->size(id)) {
147 return {};
148 }
149#endif
150 return &this->data_[this->offsets_[id] + local];
151 }
152
156 inline const SimplexId *offset_ptr() const {
157 return offsets_.data();
158 }
159
163 inline size_t size() const {
164 if(this->empty()) {
165 return 0;
166 }
167 return this->offsets_.size() - 1;
168 }
169
173 inline size_t dataSize() const {
174 return this->data_.size();
175 }
176
180 inline bool empty() const {
181 return this->data_.empty() || this->offsets_.empty();
182 }
183
187 inline size_t footprint() const {
188 return (this->data_.size() + this->offsets_.size()) * sizeof(SimplexId);
189 }
190
191 // #################### //
192 // Conversion utilities //
193 // #################### //
194
200 template <typename T>
201 void fillFrom(const std::vector<T> &src, int threadNumber = 1) {
202 this->offsets_.resize(src.size() + 1);
203 for(size_t i = 0; i < src.size(); ++i) {
204 this->offsets_[i + 1] = this->offsets_[i] + src[i].size();
205 }
206 this->data_.resize(this->offsets_.back());
207#ifdef TTK_ENABLE_OPENMP
208#pragma omp parallel for num_threads(threadNumber)
209#endif // TTK_ENABLE_OPENMP
210 for(size_t i = 0; i < src.size(); ++i) {
211 for(size_t j = 0; j < src[i].size(); ++j) {
212 this->data_[this->offsets_[i] + j] = src[i][j];
213 }
214 }
215 TTK_FORCE_USE(threadNumber);
216 }
217
221 void copyTo(std::vector<std::vector<SimplexId>> &dst,
222 int threadNumber = 1) const {
223 dst.resize(this->size());
224 for(size_t i = 0; i < this->size(); ++i) {
225 dst[i].resize((*this)[i].size());
226 }
227#ifdef TTK_ENABLE_OPENMP
228#pragma omp parallel for num_threads(threadNumber)
229#endif // TTK_ENABLE_OPENMP
230 for(size_t i = 0; i < this->size(); ++i) {
231 for(size_t j = 0; j < dst[i].size(); ++j) {
232 dst[i][j] = (*this)[i][j];
233 }
234 }
235 TTK_FORCE_USE(threadNumber);
236 }
237
238 // ##################### //
239 // Useless I/O utilities //
240 // ##################### //
241
245 inline void writeToFile(const std::string &fName) const {
246 std::ofstream out(fName);
247 for(const auto slice : *this) {
248 for(const auto el : slice) {
249 out << el << " ";
250 }
251 out << '\n';
252 }
253 }
254
258 static inline void
259 writeToFile(const std::string &fName,
260 const std::vector<std::vector<SimplexId>> &src) {
261 std::ofstream out(fName);
262 for(const auto &vec : src) {
263 for(const auto el : vec) {
264 out << el << " ";
265 }
266 out << '\n';
267 }
268 }
269 };
270} // namespace ttk
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
Definition: BaseClass.h:57
Replacement for std::vector<std::vector<SimplexId>>
size_t dataSize() const
Returns the size of the data_ member.
void copyTo(std::vector< std::vector< SimplexId > > &dst, int threadNumber=1) const
Copy buffers to a std::vector<std::vector<SimplexId>>
Slice operator[](const size_t id) const
const SimplexId * offset_ptr() const
Returns a const pointer to the offset member.
SimplexId get(SimplexId id, SimplexId local) const
Returns the data inside the sub-vectors.
static void writeToFile(const std::string &fName, const std::vector< std::vector< SimplexId > > &src)
Also write std::vector<std::vector<SimplexId>> to disk.
size_t size() const
Returns the number of sub-vectors.
void setData(std::vector< SimplexId > &&data, std::vector< SimplexId > &&offsets)
Set internal data from pre-existing vectors.
const SimplexId * get_ptr(SimplexId id, SimplexId local) const
Returns a const pointer to the data inside the sub-vectors.
size_t footprint() const
Computes the memory footprint of the array.
Iterator end() const
void fillFrom(const std::vector< T > &src, int threadNumber=1)
Fill buffers from a std::vector<std::vector<SimplexId>>
void writeToFile(const std::string &fName) const
Write content into a file.
SimplexId size(SimplexId id) const
Get the size of a particular sub-vector.
Iterator begin() const
SimplexId offset(SimplexId id) const
Get the offset of a particular sub-vector.
void clear()
Clear the underlying vectors.
bool empty() const
If the underlying buffers are empty.
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition: DataTypes.h:22
const FlatJaggedArray & parent
bool operator!=(const Iterator &other) const
const SimplexId * begin() const
const SimplexId * data() const
const SimplexId *const ptr
SimplexId operator[](const size_t id) const
const SimplexId * end() const