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.
TTK base package defining the standard types.
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