Loading...
Searching...
No Matches
piercedKernel.hpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_PIERCED_KERNEL_HPP__
26#define __BITPIT_PIERCED_KERNEL_HPP__
27
28#include <algorithm>
29#include <cassert>
30#include <limits>
31#include <unordered_map>
32#include <type_traits>
33#include <vector>
34
35#include "bitpit_common.hpp"
36
37#include "piercedSync.hpp"
38#include "piercedKernelIterator.hpp"
39#include "piercedKernelRange.hpp"
40
41namespace bitpit {
42
43template<typename id_t>
44class PiercedStorageSyncSlave;
45
47
48public:
49 virtual ~BasePiercedKernel() = default;
50
51protected:
52 BasePiercedKernel() = default;
53
54};
55
105template<typename id_t = long>
107
108static_assert(std::is_integral<id_t>::value, "Signed integer required for id.");
109static_assert(std::numeric_limits<id_t>::is_signed, "Signed integer required for id.");
110
111// Friendships
112template<typename PSI_value_t, typename PSI_id_t, typename PSI_value_no_cv_t>
113friend class PiercedStorageIterator;
114
115template<typename PKI_id_t>
116friend class PiercedKernelIterator;
117
118template<typename PKR_id_t>
119friend class PiercedKernelRange;
120
121template<typename BPS_id_t>
122friend class PiercedStorageSyncSlave;
123
124template<typename PS_value_t, typename PS_id_t>
125friend class PiercedStorage;
126
127public:
131 typedef id_t id_type;
132
137
141 typedef typename std::vector<id_t>::const_iterator raw_const_iterator;
142
147
152
157 {
158 positionLess(const PiercedKernel<id_t> &kernel)
159 {
160 m_kernel = &kernel;
161 }
162
163 bool operator()(id_t id_1, id_t id_2) const
164 {
165 return m_kernel->getPos(id_1) < m_kernel->getPos(id_2);
166 }
167
168 const PiercedKernel<id_t> *m_kernel;
169 };
170
175 {
177 {
178 m_kernel = &kernel;
179 }
180
181 bool operator()(id_t id_1, id_t id_2) const
182 {
183 return m_kernel->getPos(id_1) > m_kernel->getPos(id_2);
184 }
185
186 const PiercedKernel<id_t> *m_kernel;
187 };
188
193
194 public:
195 enum FillActionType {
196 TYPE_UNDEFINED = PiercedSyncAction::TYPE_UNDEFINED,
197 TYPE_OVERWRITE = PiercedSyncAction::TYPE_OVERWRITE,
198 TYPE_INSERT = PiercedSyncAction::TYPE_INSERT,
199 TYPE_APPEND = PiercedSyncAction::TYPE_APPEND
200 };
201
202 FillAction(FillActionType type)
204 {
205 };
206 };
207
212
213 public:
214 enum MoveActionType {
215 TYPE_UNDEFINED = PiercedSyncAction::TYPE_UNDEFINED,
216 TYPE_OVERWRITE = PiercedSyncAction::TYPE_MOVE_OVERWRITE,
217 TYPE_INSERT = PiercedSyncAction::TYPE_MOVE_INSERT,
218 TYPE_APPEND = PiercedSyncAction::TYPE_MOVE_APPEND
219 };
220
221 MoveAction(MoveActionType type)
223 {
224 };
225 };
226
231
232 public:
233 enum SwapActionType {
234 TYPE_UNDEFINED = PiercedSyncAction::TYPE_UNDEFINED,
235 TYPE_SWAP = PiercedSyncAction::TYPE_SWAP
236 };
237
238 SwapAction(SwapActionType type)
240 {
241 };
242 };
243
248
249 public:
250 enum EraseActionType {
251 TYPE_UNDEFINED = PiercedSyncAction::TYPE_UNDEFINED,
252 TYPE_PIERCE = PiercedSyncAction::TYPE_PIERCE,
253 TYPE_SHRINK = PiercedSyncAction::TYPE_RESIZE
254 };
255
256 EraseAction(EraseActionType type)
258 {
259 };
260 };
261
266
267 public:
269 : PiercedSyncAction(PiercedSyncAction::TYPE_CLEAR)
270 {
271 };
272 };
273
278
279 public:
281 : PiercedSyncAction(PiercedSyncAction::TYPE_RESERVE)
282 {
283 };
284 };
285
290
291 public:
292 enum ResizeActionType {
293 TYPE_NOOP = PiercedSyncAction::TYPE_NOOP,
294 TYPE_RESERVE = PiercedSyncAction::TYPE_RESERVE,
295 TYPE_CLEAR = PiercedSyncAction::TYPE_CLEAR,
296 TYPE_RESIZE = PiercedSyncAction::TYPE_RESIZE
297 };
298
299
300 ResizeAction(ResizeActionType type)
302 {
303 };
304 };
305
310
311 public:
312 SortAction()
313 : PiercedSyncAction(PiercedSyncAction::TYPE_REORDER)
314 {
315 };
316 };
317
322
323 public:
325 : PiercedSyncAction(PiercedSyncAction::TYPE_REORDER)
326 {
327 };
328 };
329
334
335 public:
337 : PiercedSyncAction(PiercedSyncAction::TYPE_SHRINK_TO_FIT)
338 {
339 };
340 };
341
342 // Contructors
344 PiercedKernel(std::size_t n);
345 PiercedKernel(const PiercedKernel &other) = default;
346 PiercedKernel(PiercedKernel &&other) = default;
347
348 // Destructor
349 ~PiercedKernel() override;
350
351 // Methods that modify the kernel as a whole
352 ClearAction clear(bool release = true);
353 ReserveAction reserve(std::size_t n);
354 ResizeAction resize(std::size_t n);
356 SortAction sortAfter(id_t referenceId, bool inclusive);
357 SortAction sortBefore(id_t referenceId, bool inclusive);
360
361 void swap(PiercedKernel &other) noexcept;
362
363 void flush();
364
365 // Methods that extract information about the kernel
366 bool contiguous() const;
367 void dump() const;
368 bool empty() const;
369 bool isIteratorSlow();
370 std::size_t maxSize() const;
371 std::size_t size() const;
372 std::size_t capacity() const;
373
374 // Methods that extract information about the elements of the kernel
375 bool contains(id_t id) const;
376 std::size_t count(id_t id) const;
377 std::size_t getRawIndex(id_t id) const;
378 std::size_t evalFlatIndex(id_t id) const;
379
380 std::vector<id_t> getIds(bool ordered = true) const;
381 id_t getSizeMarker(std::size_t targetSize, const id_t &fallback = -1);
382
383 // Iterators
384 const_iterator find(const id_t &id) const noexcept;
385
386 const_iterator rawFind(std::size_t pos) const noexcept;
387
388 const_iterator begin() const noexcept;
389 const_iterator end() const noexcept;
390 const_iterator cbegin() const noexcept;
391 const_iterator cend() const noexcept;
392
393 // Methods that extract information about the kernel
394 void checkIntegrity() const;
395
396 // Methods that modify the elements stored in the kernel
397 void updateId(const id_t &currentId, const id_t &updatedId);
398
399 FillAction fillHead(id_t id);
400 FillAction fillTail(id_t id);
401 FillAction fillAfter(id_t referenceId, id_t id);
402 FillAction fillBefore(id_t referenceId, id_t id);
403 FillAction fillAppend(id_t id);
404 FillAction fillHole(std::size_t hole, id_t id);
405 FillAction fillInsert(std::size_t pos, id_t id);
406
407 MoveAction moveAfter(id_t referenceId, id_t id, bool flush = false);
408 MoveAction moveBefore(id_t referenceId, id_t id, bool flush = false);
409
410 SwapAction swap(id_t id_first, id_t id_second);
411
412 EraseAction erase(id_t id, bool flush = false);
414
415 // Methods that extract information about the elements of the kernel
416 std::size_t back() const;
417 std::size_t front() const;
418
419 // Methods to handle the storage
420 using PiercedSyncMaster::sync;
422
423 // Dump and restore
424 void restore(std::istream &stream);
425 void dump(std::ostream &stream) const;
426
427protected:
431 typedef std::vector<std::size_t> holes_container;
432
437
442
443 // Methods that extract information about the kernel
444 std::size_t rawSize() const;
445
446 // Methods that extract information about the elements of the kernel
447 std::size_t findPrevUsedPos(std::size_t pos) const;
448 std::size_t findNextUsedPos(std::size_t pos) const;
449 bool isPosEmpty(std::size_t pos) const;
450 std::size_t getPos(id_t id) const;
451 std::size_t getFirstUsedPos() const;
452 std::size_t getLastUsedPos() const;
453
454 // Methods that modify the kernel as a whole
455 ClearAction _clear(bool release = true);
456 ReserveAction _reserve(std::size_t n);
457 ResizeAction _resize(std::size_t n);
458 SortAction _sort(std::size_t begin, std::size_t end);
461
462 // Methods to handle the storage
463 std::vector<PiercedStorageSyncSlave<id_t> *> getStorages();
464 std::vector<const PiercedStorageSyncSlave<id_t> *> getStorages() const;
465
466private:
482 struct PiercedHasher {
491 template<typename U>
492 constexpr std::size_t operator()(U&& value) const noexcept
493 {
494 return static_cast<std::size_t>(std::forward<U>(value));
495 }
496 };
497
507 struct idLess
508 {
509 const std::vector<id_t> &m_ids;
510
511 idLess(const std::vector<id_t> &ids)
512 : m_ids(ids)
513 {
514 }
515
516 inline bool operator() (std::size_t pos_x, std::size_t pos_y)
517 {
518 id_t id_x = m_ids[pos_x];
519 id_t id_y = m_ids[pos_y];
520
521 if (id_x >= 0 && id_y < 0) {
522 return true;
523 } else if (id_x < 0 && id_y >= 0) {
524 return false;
525 } else if (id_x >= 0) {
526 return (id_x < id_y);
527 } else {
528 return (id_x > id_y);
529 }
530 }
531 };
532
536 static const std::size_t MAX_PENDING_HOLES;
537
541 std::vector<id_t> m_ids;
542
547 std::unordered_map<id_t, std::size_t, PiercedHasher> m_pos;
548
552 std::size_t m_begin_pos;
553
557 std::size_t m_end_pos;
558
566 std::size_t m_dirty_begin_pos;
567
572 holes_container m_holes;
573
577 std::size_t m_holes_regular_begin;
578
582 std::size_t m_holes_regular_end;
583
587 std::size_t m_holes_pending_begin;
588
592 std::size_t m_holes_pending_end;
593
597 bool m_holes_regular_sorted;
598
602 bool m_holes_pending_sorted;
603
604 void pierce(std::size_t pos, bool flush = true);
605
606 void holesClear(bool release = false);
607 void holesClearRegular(bool release = false);
608 void holesClearPending(bool release = false);
609 void holesResize(std::size_t offset, std::size_t nRegulars, std::size_t nPendings, bool release = true);
610 std::size_t holesCount() const;
611 std::size_t holesCountPending() const;
612 std::size_t holesCountRegular() const;
613 void holesFlush();
614 void holesSortPending();
615 void holesSortRegular();
616
617 bool validateId(id_t id);
618
619 void setBeginPos(std::size_t pos);
620 void setEndPos(std::size_t pos);
621
622 void setPosId(std::size_t pos, id_t id);
623 void setPosEmptyId(std::size_t pos, std::size_t nextUsedPos);
624 void swapPosIds(std::size_t pos_1, id_t id_1, std::size_t pos_2, id_t id_2);
625
626 void rawShrink(std::size_t n);
627
628};
629
630}
631
632// Include the implementation
633#include "piercedKernel.tpp"
634
635
636#endif
Base class for the pierced kernel.
Iterator for the class PiercedKernel.
The PiercedKernelRange allow to iterate using range-based loops over a PiercedStorage.
Metafunction for generating a pierced kernel.
ResizeAction resize(std::size_t n)
std::size_t getPos(id_t id) const
const_iterator rawFind(std::size_t pos) const noexcept
PiercedKernelIterator< id_t > const_iterator
FillAction fillHole(std::size_t hole, id_t id)
bool isPosEmpty(std::size_t pos) const
std::vector< id_t > getIds(bool ordered=true) const
SqueezeAction _squeeze()
std::size_t rawSize() const
PiercedKernelRange< id_t > const_range
std::size_t findNextUsedPos(std::size_t pos) const
std::size_t findPrevUsedPos(std::size_t pos) const
SortAction sortBefore(id_t referenceId, bool inclusive)
ResizeAction _resize(std::size_t n)
void updateId(const id_t &currentId, const id_t &updatedId)
const_iterator cend() const noexcept
EraseAction erase(id_t id, bool flush=false)
const_iterator find(const id_t &id) const noexcept
FillAction fillAppend(id_t id)
SqueezeAction squeeze()
bool contains(id_t id) const
ClearAction _clear(bool release=true)
std::size_t getRawIndex(id_t id) const
const_iterator begin() const noexcept
MoveAction moveAfter(id_t referenceId, id_t id, bool flush=false)
ClearAction clear(bool release=true)
ReserveAction reserve(std::size_t n)
std::size_t getFirstUsedPos() const
SortAction _sort(std::size_t begin, std::size_t end)
id_t getSizeMarker(std::size_t targetSize, const id_t &fallback=-1)
FillAction fillAfter(id_t referenceId, id_t id)
FillAction fillBefore(id_t referenceId, id_t id)
FillAction fillInsert(std::size_t pos, id_t id)
std::size_t count(id_t id) const
std::size_t front() const
ShrinkToFitAction _shrinkToFit()
const_iterator cbegin() const noexcept
void swap(PiercedKernel &other) noexcept
holes_container::const_iterator holes_const_iterator
std::size_t evalFlatIndex(id_t id) const
FillAction fillHead(id_t id)
std::size_t maxSize() const
void restore(std::istream &stream)
SortAction sortAfter(id_t referenceId, bool inclusive)
std::vector< id_t >::const_iterator raw_const_iterator
const_iterator end() const noexcept
ShrinkToFitAction shrinkToFit()
std::size_t capacity() const
std::size_t getLastUsedPos() const
FillAction fillTail(id_t id)
std::vector< std::size_t > holes_container
std::size_t size() const
MoveAction moveBefore(id_t referenceId, id_t id, bool flush=false)
ReserveAction _reserve(std::size_t n)
std::vector< PiercedStorageSyncSlave< id_t > * > getStorages()
std::size_t back() const
holes_container::iterator holes_iterator
Iterator for the class PiercedStorage.
Base class for defining storages that acts like a slave in pierced synchronization.
Metafunction for generating a pierced storage.
Action for pierced synchronization.
PiercedSyncAction(ActionType _type=TYPE_UNDEFINED)
Base class for defining an object that acts like a master in pierced synchronization.
--- layout: doxygen_footer ---