The Sparta Modeling Framework
Loading...
Searching...
No Matches
Array.hpp
Go to the documentation of this file.
1// <Array.hpp> -*- C++ -*-
2
8#pragma once
9
10#include <cinttypes>
11#include <vector>
12#include <string>
13#include <memory>
14
17#include "sparta/collection/IterableCollector.hpp"
19
20namespace sparta
21{
27 enum class ArrayType {
28 NORMAL,
29 AGED
30 };
31
56 template<class DataT, ArrayType ArrayT = ArrayType::AGED>
57 class Array
58 {
59 private:
61 struct ArrayPosition{
62 ArrayPosition() :
63 valid(false),
64 to_validate(false){}
65
66 template<typename U>
67 explicit ArrayPosition(U && data) :
68 data(std::forward<U>(data)){}
69
70 bool valid;
71 bool to_validate;
72 DataT data;
73 std::list<uint32_t>::iterator list_pointer;
74 uint64_t age_abs_id = 0; // Absolute ID of all allocations
75 uint32_t age_rel_id = 0; // Relative ID of current allocations
76 };
77
79 typedef std::vector<ArrayPosition> ArrayVector;
80
83
84 public:
85
87 typedef DataT value_type;
88
90 typedef DataT DataType;
91
93 typedef uint32_t size_type;
94
96 typedef std::list<uint32_t> AgedList;
97
109 template<bool is_const_iterator = true>
110 struct ArrayIterator : public utils::IteratorTraits<std::forward_iterator_tag, value_type>
111 {
112 private:
113
114 typedef typename std::conditional<is_const_iterator,
115 const value_type &,
116 value_type &>::type DataReferenceType;
117
118 typedef typename std::conditional<is_const_iterator,
119 const FullArrayType *,
120 FullArrayType *>::type ArrayPointerType;
121 friend FullArrayType;
122
124 ArrayIterator(ArrayPointerType array,
125 uint32_t start_index,
126 bool is_aged,
127 bool is_circular,
128 bool is_aged_walk) :
129 index_(start_index),
130 array_(array),
131 is_aged_(is_aged),
132 is_circular_(is_circular),
133 is_aged_walk_(is_aged_walk)
134 {}
135
138 operator uint32_t() const {
139 return index_;
140 }
141
143 DataReferenceType getAccess_(std::false_type) {
144 return array_->access(index_);
145 }
146
148 DataReferenceType getAccess_(std::true_type) const {
149 return array_->read(index_);
150 }
151
152 // Allow the creation of a const iterator from non-const
154 public:
155
159 ArrayIterator() = default;
160
166 index_(other.index_),
167 array_(other.array_),
168 is_aged_(other.is_aged_),
169 is_circular_(other.is_circular_),
170 is_aged_walk_(other.is_aged_walk_)
171 {}
172
178 index_(other.index_),
179 array_(other.array_),
180 is_aged_(other.is_aged_),
181 is_circular_(other.is_circular_),
182 is_aged_walk_(other.is_aged_walk_)
183 {}
184
188 ArrayIterator& operator=(const ArrayIterator& other) = default;
189
191 void reset()
192 {
193 index_ = sparta::notNull(array_)->capacity();
194 }
195
197 bool isIndexValid() const
198 {
199 return (index_ < sparta::notNull(array_)->capacity());
200 }
201
203 uint32_t getIndex() const
204 {
205 sparta_assert(index_ != sparta::notNull(array_)->invalid_entry_,
206 "Cannot operate on an unitialized iterator.");
207 return index_;
208 }
209
211 bool isValid() const
212 {
213 return (array_ != nullptr) &&
214 (index_ != array_->invalid_entry_) &&
215 (array_->isValid(index_));
216 }
217
225 bool isOlder(const uint32_t idx) const
226 {
227 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
228 "Cannot operate on an uninitialized iterator.");
229 return array_->isOlder(index_, idx);
230 }
231
233 bool isOlder(const ArrayIterator & other) const
234 {
235 return isOlder(other.index_);
236 }
237
248 bool isYounger(const uint32_t idx) const
249 {
250 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
251 "Cannot operate on an uninitialized iterator.");
252 return sparta::notNull(array_)->isYounger(index_, idx);
253 }
254
256 bool isYounger(const ArrayIterator & other) const
257 {
258 return isYounger(other.index_);
259 }
260
263 bool operator<(const ArrayIterator &rhs) const {
264 return isYounger(rhs);
265 }
266
267 bool operator==(const ArrayIterator& rhs) const
268 {
269 return (rhs.index_ == index_) && (rhs.array_ == array_);
270 }
271
272 bool operator==(const uint32_t & rhs) const
273 {
274 return (rhs == index_);
275 }
276
277 bool operator!=(const ArrayIterator& rhs) const
278 {
279 return (rhs.index_ != index_) || (rhs.array_ != array_);
280 }
281
283 DataReferenceType operator*() {
284 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
285 "Cannot operate on an uninitialized iterator.");
286 // return the data at our location in the array.
287 return getAccess_(std::integral_constant<bool, is_const_iterator>());
288 }
289
291 DataReferenceType operator*() const {
292 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
293 "Cannot operate on an uninitialized iterator.");
294 // return the data at our location in the array.
295 return getAccess_(std::integral_constant<bool, is_const_iterator>());
296 }
297
299 value_type* operator->()
300 {
301 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
302 "Cannot operate on an uninitialized iterator.");
303 return std::addressof(getAccess_(std::integral_constant<bool, is_const_iterator>()));
304 }
305
306 const value_type* operator->() const
307 {
308 sparta_assert(index_ < sparta::notNull(array_)->capacity(),
309 "Cannot operate on an uninitialized iterator.");
310 return std::addressof(getAccess_(std::integral_constant<bool, is_const_iterator>()));
311 }
312
315 {
316 sparta_assert(index_ != sparta::notNull(array_)->invalid_entry_,
317 "Cannot operate on an uninitialized iterator.");
318 if(is_aged_walk_) {
319 if(!sparta::notNull(array_)->getNextOldestIndex(index_)) {
320 index_ = (sparta::notNull(array_)->getOldestIndex());
321 }
322 }
323 else {
324 ++index_;
325 if(index_ == sparta::notNull(array_)->capacity()) {
326 index_ = 0;
327 }
328 }
329 if(is_circular_) { return *this; }
330
331 // Aged iterators will act circular if the array is
332 // filled with valid entries.
333 if(is_aged_)
334 {
335 // We've wrapped around -- we're done.
336 if(*this == sparta::notNull(array_)->abegin()) {
337 *this = sparta::notNull(array_)->aend();
338 }
339 else {
340 // If the iterator is not pointing to a valid
341 // entry, try again.
342 if(!isValid()) {
343 this->operator++();
344 }
345 }
346 }
347 else {
348 if(*this == sparta::notNull(array_)->begin()) {
349 // We've wrapped around and have hit begin. We're at
350 // the end now.
351 *this = sparta::notNull(array_)->end();
352 }
353 }
354 return *this;
355 }
356
359 {
360 iterator old_iter(*this);
361 // do the same functionality as the pre increment.
362 operator++();
363 // return the state before the increment.
364 return old_iter;
365 }
366
367 private:
368 uint32_t index_ = std::numeric_limits<uint32_t>::max();
369 ArrayPointerType array_ = nullptr;
370 bool is_aged_ = false;
371 bool is_circular_ = false;
372 bool is_aged_walk_ = false;
373 };
374
377
380
387 {
388 constexpr bool is_aged = false;
389 constexpr bool is_circular = true;
390 constexpr bool is_aged_walk = false;
391 return iterator(this, idx, is_aged, is_circular, is_aged_walk);
392 }
393
396 {
397 constexpr bool is_aged = false;
398 constexpr bool is_circular = false;
399 constexpr bool is_aged_walk = false;
400 return iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
401 }
402
406 constexpr bool is_aged = false;
407 constexpr bool is_circular = false;
408 constexpr bool is_aged_walk = false;
409 return iterator(this, 0, is_aged, is_circular, is_aged_walk);
410 }
411
415 constexpr bool is_aged = false;
416 constexpr bool is_circular = false;
417 constexpr bool is_aged_walk = false;
418 return const_iterator(this, 0, is_aged, is_circular, is_aged_walk);
419 }
420
424 constexpr bool is_aged = false;
425 constexpr bool is_circular = false;
426 constexpr bool is_aged_walk = false;
427 return iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
428 }
429
433 constexpr bool is_aged = false;
434 constexpr bool is_circular = false;
435 constexpr bool is_aged_walk = false;
436 return const_iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
437 }
438
442 constexpr bool is_aged = true;
443 constexpr bool is_circular = false;
444 constexpr bool is_aged_walk = true;
445 if(numValid()) {
446 return iterator(this, getOldestIndex().getIndex(), is_aged, is_circular, is_aged_walk);
447 }
448 return iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
449 }
450
455 constexpr bool is_aged = true;
456 constexpr bool is_circular = false;
457 constexpr bool is_aged_walk = true;;
458 if(numValid()) {
459 return getOldestIndex();
460 }
461 return const_iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
462 }
463
467 constexpr bool is_aged = true;
468 constexpr bool is_circular = false;
469 constexpr bool is_aged_walk = true;
470 return iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
471 }
472
476 constexpr bool is_aged = true;
477 constexpr bool is_circular = false;
478 constexpr bool is_aged_walk = true;
479 return const_iterator(this, invalid_entry_, is_aged, is_circular, is_aged_walk);
480 }
481
518 Array(const std::string& name, uint32_t num_entries, const Clock* clk,
519 StatisticSet* statset = nullptr,
524
526 virtual ~Array() {
527 clear();
528 }
529
533 const std::string & getName() const {
534 return name_;
535 }
536
541 bool isValid(const uint32_t idx) const {
542 return valid_index_set_.find(idx) != valid_index_set_.end();
543 }
544
550 const DataT& read(const uint32_t idx) const {
551 sparta_assert(isValid(idx), "On Array " << name_
552 << " Cannot read from an invalid index. Idx:" << idx);
553 return array_[idx].data;
554 }
555
560 DataT& access(const uint32_t idx) {
561 sparta_assert(isValid(idx), "On Array " << name_
562 << " Cannot read from an invalid index. Idx:" << idx);
563 return (array_[idx].data);
564 }
565
578 const_iterator getOldestIndex(const uint32_t nth=0) const
579 {
581 "Only AgedArray types have public member function getOldestIndex");
582 sparta_assert(nth < num_valid_,
583 "The array does not have enough elements to find the nth oldest index");
584
585 constexpr bool is_aged = true;
586 constexpr bool is_circular = false;
587 constexpr bool is_aged_walk = true;
588
589 // Since our data_list_ always adds new items to the
590 // front. The oldest data is actually kept at the end of
591 // the list. We can iterate from the end to find the nth
592 // oldest item.
593 auto it = aged_list_.rbegin();
594 uint32_t idx = invalid_entry_;
595 for(uint32_t i = 0; i <= nth; ++i)
596 {
597 idx = *it;
598 ++it;
599 }
600 // Double check that we are returning the user a valid
601 // index. We have failed if it isn't.
603 return const_iterator(this, idx, is_aged, is_circular, is_aged_walk);
604 }
605
616 const_iterator getYoungestIndex(const uint32_t nth=0) const
617 {
619 "Only AgedArray types provide access to public member"
620 " function getYoungestIndex");
621 sparta_assert(nth < num_valid_,
622 "The array does not have enough elements to find the nth youngest index");
623 constexpr bool is_aged = true;
624 constexpr bool is_circular = false;
625 constexpr bool is_aged_walk = true;
626
627 // Define idx, and set it to a value surely beyond the bounds of our array.
628 uint32_t idx = invalid_entry_;
629 auto it = aged_list_.begin();
630 for(uint32_t i = 0; i <= nth; ++i)
631 {
632 idx = *it;
633 ++it;
634 }
635 // Make sure we found something valid.
637 return const_iterator(this, idx, is_aged, is_circular, is_aged_walk);
638 }
639
645 bool getNextOldestIndex(uint32_t & prev_idx) const {
646 auto it = std::find(aged_list_.begin(), aged_list_.end(), prev_idx);
647 if(it == aged_list_.begin()) {
648 return false;
649 }
650 --it;
651 prev_idx = *it;
652 return true;
653 }
654
659 uint32_t getAge(const uint32_t idx) const {
661 "Only AgedArray types provides age information");
663 return array_[idx].age_rel_id;
664 }
665
669 const AgedList & getAgedList() const
670 {
672 return aged_list_;
673 }
674
681 return num_entries_;
682 }
683
689 return num_valid_;
690 }
691
693 size_type size() const {
694 return numValid();
695 }
696
702 sparta_assert(num_entries_ >= num_valid_);
703 return num_entries_ - num_valid_;
704 }
705
710 void erase(const iterator& iter) {
711 sparta_assert(iter.isValid());
712 erase(iter.getIndex());
713 }
714
719 void erase(const uint32_t& idx)
720 {
721 sparta_assert(isValid(idx), "Cannot invalidate a non valid index.");
722 sparta_assert(num_valid_ > 0);
723
724 // Just set the data to invalid.
725 array_[idx].valid = false;
726 --num_valid_;
727
728 if constexpr (ArrayT == ArrayType::AGED)
729 {
730 // Remove the index from our aged list.
731 aged_list_.erase(array_[idx].list_pointer);
732 // Update the relative age IDs
733 updateRelativeAge_();
734 }
735
736 // Update occupancy counter.
737 if(utilization_)
738 {
739 utilization_->setValue(num_valid_);
740 }
741 array_[idx].~ArrayPosition();
742 valid_index_set_.erase(idx);
743 }
744
748 void clear()
749 {
750 std::for_each(valid_index_set_.begin(), valid_index_set_.end(), [this](const auto index){
751 array_[index].~ArrayPosition();
752 });
753 valid_index_set_.clear();
754 aged_list_.clear();
755 num_valid_ = 0;
756 if(utilization_)
757 {
758 utilization_->setValue(num_valid_);
759 }
760 }
761
770 void write(const uint32_t idx, const DataT& dat)
771 {
772 writeImpl_(idx, dat);
773 }
774
783 void write(const uint32_t idx, DataT&& dat)
784 {
785 writeImpl_(idx, std::move(dat));
786 }
787
796 void write(const iterator& iter, const DataT& dat)
797 {
798 write(iter.getIndex(), dat);
799 }
800
809 void write(const iterator& iter, DataT&& dat)
810 {
811 write(iter.getIndex(), std::move(dat));
812 }
813
821 bool isYounger(uint32_t lhs, uint32_t rhs)
822 {
823 sparta_assert(lhs != rhs);
824 sparta_assert(lhs < num_entries_ && rhs < num_entries_,
825 "Cannot compare age on an index outside the bounds of the array");
826 return array_[lhs].age_abs_id > array_[rhs].age_abs_id;
827 }
828
836 bool isOlder(uint32_t lhs, uint32_t rhs)
837 {
838 sparta_assert(lhs != rhs);
839 sparta_assert(lhs < num_entries_ && rhs < num_entries_,
840 "Cannot compare age on an index outside the bounds of the array");
841 return array_[lhs].age_abs_id < array_[rhs].age_abs_id;
842 }
843
849 {
850 // Create the collector instance of the appropriate type.
851 sparta_assert(parent != nullptr);
852 collector_.
855 (parent, name_, this, capacity()));
856
857 if constexpr (ArrayT == ArrayType::AGED) {
859 (parent, name_ + "_age_ordered",
860 &aged_array_col_, capacity()));
861 }
862 }
863
864 private:
865
866 class AgedArrayCollectorProxy
867 {
868 public:
870 typedef uint32_t size_type;
871
872 AgedArrayCollectorProxy(FullArrayType * array) : array_(array) { }
873
874 typedef FullArrayType::iterator iterator;
875
876 FullArrayType::iterator begin() const {
877 return array_->abegin();
878 }
879
880 FullArrayType::iterator end() const {
881 return array_->aend();
882 }
883
884 uint32_t size() const {
885 return array_->size();
886 }
887
888 private:
889 FullArrayType * array_ = nullptr;
890 };
891
896 const AgedList & getInternalAgedList_() const
897 {
899 return aged_list_;
900 }
901
908 void updateRelativeAge_()
909 {
911
912 // Since our data_list_ always adds new items to the
913 // front. The oldest data is actually kept at the end of
914 // the list. We can iterate from the end to find the nth
915 // oldest item.
916 auto it = aged_list_.rbegin();
917 uint32_t idx = invalid_entry_;
918 const uint32_t size = aged_list_.size();
919 for(uint32_t i = 0; i < size; ++i)
920 {
921 idx = *it;
922 ++it;
923 // Double check that it's a valid index.
925 // Upate the relaive age ID
926 array_[idx].age_rel_id = i;
927 }
928 }
929
930 template<typename U>
931 void writeImpl_(const uint32_t idx, U&& dat)
932 {
933 sparta_assert(idx < num_entries_,
934 "Cannot write to an index outside the bounds of the array.");
935
936 // We're overwriting an entry, clear valid and age information.
938 {
939 --num_valid_;
940 if constexpr (ArrayT == ArrayType::AGED) {
941 aged_list_.erase(array_[idx].list_pointer);
942 }
943 }
944
945 // Since we are not timed. Write the data and validate it,
946 // then do pipeline collection.
947 new (array_.get() + idx) ArrayPosition(std::forward<U>(dat));
948 valid_index_set_.insert(idx);
949
950 // Timestamp the entry in the array, for fast age comparison between two indexes.
951 array_[idx].age_abs_id = next_age_abs_id_;
952 ++next_age_abs_id_;
953
954 // Validate the entry and increase valids
955 array_[idx].valid = true;
956 ++num_valid_;
957
958 // Maintain our age order if we are an aged array.
959 if constexpr (ArrayT == ArrayType::AGED)
960 {
961 // To maintain aged items, add the index to the front
962 // of a list.
963 aged_list_.push_front(idx);
964 array_[idx].list_pointer = aged_list_.begin();
965 // Update the relative age IDs
966 updateRelativeAge_();
967 }
968
969 // Update occupancy counter.
970 if(utilization_)
971 {
972 utilization_->setValue(num_valid_);
973 }
974 }
975
976 const std::string name_;
977
978 struct DeleteToFree_{
979 void operator()(void * x){
980 free(x);
981 }
982 };
983
984 // The size of our array.
985 const size_type num_entries_;
986 const uint32_t invalid_entry_{num_entries_ + 1};
987
988 // The number of valid positions after last update.
989 size_type num_valid_;
990
991 // A vector that holds all of our data, contains valid and
992 // invalid data.
993 std::unique_ptr<ArrayPosition[], DeleteToFree_> array_ = nullptr;
994
995 // Set to hold valid indexes at a time
996 std::unordered_set<uint32_t> valid_index_set_ {};
997
998 // The aged list.
999 AgedList aged_list_;
1000 AgedArrayCollectorProxy aged_array_col_{this};
1001
1002 // A counter used to assign a unique age id to every newly
1003 // written valid entry to the array for fast age comparisons
1004 // between indexes.
1005 uint64_t next_age_abs_id_;
1006
1008 // Counters
1009 std::unique_ptr<sparta::CycleHistogramStandalone> utilization_;
1010
1012 // Collectors
1013 std::unique_ptr<collection::IterableCollector<FullArrayType,
1015 true>> collector_;
1016 std::unique_ptr<collection::IterableCollector<AgedArrayCollectorProxy> > age_collector_;
1017 };
1018
1019 template<class DataT, ArrayType ArrayT>
1020 Array<DataT, ArrayT>::Array(const std::string& name,
1021 uint32_t num_entries,
1022 const Clock* clk,
1023 StatisticSet* statset,
1024 InstrumentationNode::visibility_t stat_vis_general,
1025 InstrumentationNode::visibility_t stat_vis_detailed,
1027 InstrumentationNode::visibility_t stat_vis_avg) :
1028 name_(name),
1029 num_entries_(num_entries),
1030 num_valid_(0),
1031 next_age_abs_id_(0)
1032 {
1033 // Set up some vector's of a default size
1034 // to work as the underlying implementation structures of our array.
1035 array_.reset(static_cast<ArrayPosition *>(malloc(sizeof(ArrayPosition) * num_entries_)));
1036
1037 if((num_entries > 0) && statset)
1038 {
1039 utilization_.reset(new CycleHistogramStandalone(statset, clk,
1040 name + "_utilization",
1041 name + " occupancy histogram",
1042 0, num_entries_, 1, 0,
1043 stat_vis_general,
1044 stat_vis_detailed,
1045 stat_vis_max,
1046 stat_vis_avg));
1047 }
1048 }
1049
1050}
CycleHistogram implementation using sparta CycleCounter.
Defines a few handy (and now deprecated) C++ iterator traits.
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
#define SPARTA_EXPECT_FALSE(x)
A macro for hinting to the compiler a particular condition should be considered most likely false.
Array is essentially a fixed size vector, maintains a concept of validity of its indexes,...
Definition Array.hpp:58
void erase(const uint32_t &idx)
Invalidate the entry at a certain index.
Definition Array.hpp:719
size_type size() const
Definition Array.hpp:693
size_type capacity() const
Return the maximum number of elements this Array can hold.
Definition Array.hpp:680
void write(const iterator &iter, const DataT &dat)
Write data at an iterator position.
Definition Array.hpp:796
iterator end()
STL-like end operation.
Definition Array.hpp:423
iterator abegin()
STL-like begin operation, starts at the oldest valid index.
Definition Array.hpp:441
bool getNextOldestIndex(uint32_t &prev_idx) const
Sets the input argument to the index containing the location of the next oldest item after input argu...
Definition Array.hpp:645
ArrayIterator< true > const_iterator
Typedef for constant iterator.
Definition Array.hpp:379
const std::string & getName() const
Name of this resource.
Definition Array.hpp:533
const AgedList & getAgedList() const
Provide access to our aged_list_ internals.
Definition Array.hpp:669
void write(const uint32_t idx, const DataT &dat)
Write data to the array.
Definition Array.hpp:770
size_type numFree() const
The number of free entries.
Definition Array.hpp:701
DataT & access(const uint32_t idx)
Access (writeable) the data at a position.
Definition Array.hpp:560
Array(const std::string &name, uint32_t num_entries, const Clock *clk, StatisticSet *statset=nullptr, InstrumentationNode::visibility_t stat_vis_general=InstrumentationNode::AUTO_VISIBILITY, InstrumentationNode::visibility_t stat_vis_detailed=InstrumentationNode::VIS_HIDDEN, InstrumentationNode::visibility_t stat_vis_max=InstrumentationNode::AUTO_VISIBILITY, InstrumentationNode::visibility_t stat_vis_avg=InstrumentationNode::AUTO_VISIBILITY)
Construct an array.
Definition Array.hpp:1020
const_iterator getYoungestIndex(const uint32_t nth=0) const
provide access the youngest index in the array.
Definition Array.hpp:616
bool isValid(const uint32_t idx) const
Determine whether an index is currently valid.
Definition Array.hpp:541
iterator aend()
STL-like end operation.
Definition Array.hpp:466
const_iterator getOldestIndex(const uint32_t nth=0) const
Return the oldest index in the array.
Definition Array.hpp:578
uint32_t getAge(const uint32_t idx) const
Provide the age information of the given entry index.
Definition Array.hpp:659
const_iterator aend() const
STL-like end operation, const.
Definition Array.hpp:475
const DataT & read(const uint32_t idx) const
Read (only) the data at an index.
Definition Array.hpp:550
DataT DataType
Expected typedef for the data that will be stored in this structure.
Definition Array.hpp:90
const_iterator abegin() const
STL-like begin operation, const, starts at the oldest valid index.
Definition Array.hpp:454
iterator begin()
STL-like begin operation, starts at index 0 (ignores valid bit).
Definition Array.hpp:405
std::list< uint32_t > AgedList
Typedef for a list of indexes in age order.
Definition Array.hpp:96
ArrayIterator< false > iterator
Typedef for regular iterator.
Definition Array.hpp:376
uint32_t size_type
Typedef for size_type.
Definition Array.hpp:93
void write(const iterator &iter, DataT &&dat)
Write data at an iterator position.
Definition Array.hpp:809
void enableCollection(TreeNode *parent)
Set up a auto-collector for this Array.
Definition Array.hpp:848
iterator getUnitializedIterator()
Provide a method to get an uninitialized iterator.
Definition Array.hpp:395
bool isYounger(uint32_t lhs, uint32_t rhs)
Determine if an index was written (using write()) to the Array after another index.
Definition Array.hpp:821
DataT value_type
The data type, STL style.
Definition Array.hpp:87
const_iterator begin() const
STL-like begin operation, const, starts at index 0 (ignores valid bit).
Definition Array.hpp:414
iterator getCircularIterator(uint32_t idx=0)
Get an iterator that is circular on the Array (has no end())
Definition Array.hpp:386
bool isOlder(uint32_t lhs, uint32_t rhs)
Determine if an index was written (using write()) to the Array before another index.
Definition Array.hpp:836
size_type numValid() const
The number of valid entries contained.
Definition Array.hpp:688
virtual ~Array()
Virtual destructor.
Definition Array.hpp:526
const_iterator end() const
STL-like end operation, const.
Definition Array.hpp:432
void erase(const iterator &iter)
Invalidate data at an iterator position.
Definition Array.hpp:710
void clear()
Clear the array of all data.
Definition Array.hpp:748
void write(const uint32_t idx, DataT &&dat)
Write data to the array.
Definition Array.hpp:783
A representation of simulated time.
Definition Clock.hpp:51
CycleHistogramStandalone class for uint64_t values.
uint32_t visibility_t
Continuous visibility level. Several key points along continum are indicated within Visibility.
@ VIS_HIDDEN
Hidden hint. Lowest possible visibility.
static constexpr visibility_t AUTO_VISIBILITY
The default sparta resource visibility value that should be used. This is an alias of VIS_MAX at the ...
Set of StatisticDef and CounterBase-derived objects for visiblility through a sparta Tree.
Node in a composite tree representing a sparta Tree item.
Definition TreeNode.hpp:205
A collector of any iterable type (std::vector, std::list, sparta::Buffer, etc)
Macros for handling exponential backoff.
ArrayType
Defines how a sparta::Array should behave. The array will have different features depending on the ty...
Definition Array.hpp:27
T * notNull(T *p)
Ensures that a pointer is not null.
Definition Utils.hpp:224
@ Collection
Pipeline collection occurs here.
An iterator struct for this array.
Definition Array.hpp:111
ArrayIterator operator++(int)
post-increment operator.
Definition Array.hpp:358
ArrayIterator & operator++()
pre-increment operator.
Definition Array.hpp:314
bool isYounger(const ArrayIterator &other) const
Overload isYounger to accept another iterator instead of index.
Definition Array.hpp:256
bool isIndexValid() const
Determine whether this iterator has been initialized with a valid index.
Definition Array.hpp:197
DataReferenceType operator*() const
support the dereference operator, const
Definition Array.hpp:291
DataReferenceType operator*()
support the dereference operator, non-const
Definition Array.hpp:283
bool isValid() const
Determine whether this array entry pointed to by this iterator is valid.
Definition Array.hpp:211
ArrayIterator()=default
Default constructor.
ArrayIterator & operator=(const ArrayIterator &other)=default
Assignment operator.
bool isOlder(const ArrayIterator &other) const
Overload isOlder to accept another iterator instead of an index.
Definition Array.hpp:233
ArrayIterator(const ArrayIterator< true > &other)
a copy constructor that allows for implicit conversion from a const_iterator to a regular iterator.
Definition Array.hpp:177
bool isYounger(const uint32_t idx) const
determine if the data at this iterator was written to more recently than another index.
Definition Array.hpp:248
value_type * operator->()
support -> operator.
Definition Array.hpp:299
bool operator<(const ArrayIterator &rhs) const
Definition Array.hpp:263
ArrayIterator(const ArrayIterator< false > &other)
a copy constructor that allows for implicit conversion from a regular iterator to a const_iterator.
Definition Array.hpp:165
uint32_t getIndex() const
What index does our iterator currently represent.
Definition Array.hpp:203
bool isOlder(const uint32_t idx) const
determine if the data at this iterator was written before the data at another index.
Definition Array.hpp:225
void reset()
Reset the iterator to an invalid value.
Definition Array.hpp:191