Skip to content

Commit 1477609

Browse files
bdutroklingaard
andauthored
sparta::Buffer Enhancements (#527)
* First cut of Buffer::erase returning next itr * Fixed bugs in tester for new erase * Buffer::erase now returns a non-const iterator; trying to get reverse working * Make sparta::Buffer::reverse_iterator behave more like an STL reverse_iterator - rbegin() iterator now correctly dereferences to the entry before end() - Minor quirk: because end() is a constant, rbegin() will always be valid after an erase() or pop_back() as long as the Buffer is not empty --------- Co-authored-by: Knute Lingaard <klingaard@gmail.com>
1 parent 9d0b54b commit 1477609

File tree

2 files changed

+173
-56
lines changed

2 files changed

+173
-56
lines changed

sparta/sparta/resources/Buffer.hpp

+51-45
Original file line numberDiff line numberDiff line change
@@ -208,28 +208,32 @@ namespace sparta
208208
/// override the comparison operator.
209209
bool operator<(const BufferIterator& rhs) const
210210
{
211-
sparta_assert(attached_buffer_ == rhs.attached_buffer_, "Cannot compare BufferIterators created by different buffers.");
211+
sparta_assert(attached_buffer_ == rhs.attached_buffer_,
212+
"Cannot compare BufferIterators created by different buffers.");
212213
return getIndex_() < rhs.getIndex_();
213214
}
214215

215216
/// override the comparison operator.
216217
bool operator>(const BufferIterator& rhs) const
217218
{
218-
sparta_assert(attached_buffer_ == rhs.attached_buffer_, "Cannot compare BufferIterators created by different buffers.");
219+
sparta_assert(attached_buffer_ == rhs.attached_buffer_,
220+
"Cannot compare BufferIterators created by different buffers.");
219221
return getIndex_() > rhs.getIndex_();
220222
}
221223

222224
/// override the comparison operator.
223225
bool operator==(const BufferIterator& rhs) const
224226
{
225-
sparta_assert(attached_buffer_ == rhs.attached_buffer_, "Cannot compare BufferIterators created by different buffers.");
227+
sparta_assert(attached_buffer_ == rhs.attached_buffer_,
228+
"Cannot compare BufferIterators created by different buffers.");
226229
return (buffer_entry_ == rhs.buffer_entry_);
227230
}
228231

229232
/// override the not equal operator.
230233
bool operator!=(const BufferIterator& rhs) const
231234
{
232-
sparta_assert(attached_buffer_ == rhs.attached_buffer_, "Cannot compare BufferIterators created by different buffers.");
235+
sparta_assert(attached_buffer_ == rhs.attached_buffer_,
236+
"Cannot compare BufferIterators created by different buffers.");
233237
return !operator==(rhs);
234238
}
235239

@@ -245,39 +249,39 @@ namespace sparta
245249

246250
/// override the dereferencing operator
247251
DataReferenceType operator* () const {
248-
sparta_assert(attached_buffer_, "The iterator is not attached to a buffer. Was it initialized?");
252+
sparta_assert(attached_buffer_,
253+
"The iterator is not attached to a buffer. Was it initialized?");
249254
sparta_assert(isValid(), "Iterator is not valid for dereferencing");
250255
return *(buffer_entry_->data);
251256
}
252257

253258
//! Overload the class-member-access operator.
254259
value_type * operator -> () {
255-
sparta_assert(attached_buffer_, "The iterator is not attached to a buffer. Was it initialized?");
260+
sparta_assert(attached_buffer_,
261+
"The iterator is not attached to a buffer. Was it initialized?");
256262
sparta_assert(isValid(), "Iterator is not valid for dereferencing");
257263
return buffer_entry_->data;
258264
}
259265

260266
value_type const * operator -> () const {
261-
sparta_assert(attached_buffer_, "The iterator is not attached to a buffer. Was it initialized?");
267+
sparta_assert(attached_buffer_,
268+
"The iterator is not attached to a buffer. Was it initialized?");
262269
sparta_assert(isValid(), "Iterator is not valid for dereferencing");
263270
return buffer_entry_->data;
264271
}
265272

266273
/** brief Move the iterator forward to point to next element in queue ; PREFIX
267274
*/
268275
BufferIterator & operator++() {
269-
sparta_assert(attached_buffer_, "The iterator is not attached to a buffer. Was it initialized?");
270-
if(isValid()) {
271-
uint32_t idx = buffer_entry_->physical_idx;
272-
++idx;
273-
if(attached_buffer_->isValid(idx)) {
274-
buffer_entry_ = attached_buffer_->buffer_map_[idx];
275-
}
276-
else {
277-
buffer_entry_ = nullptr;
278-
}
279-
} else {
280-
sparta_assert(attached_buffer_->numFree() > 0, "Incrementing the iterator to entry that is not valid");
276+
sparta_assert(attached_buffer_,
277+
"The iterator is not attached to a buffer. Was it initialized?");
278+
sparta_assert(isValid(), "Incrementing an iterator that is not valid");
279+
const uint32_t idx = buffer_entry_->physical_idx + 1;
280+
if(attached_buffer_->isValid(idx)) {
281+
buffer_entry_ = attached_buffer_->buffer_map_[idx];
282+
}
283+
else {
284+
buffer_entry_ = nullptr;
281285
}
282286
return *this;
283287
}
@@ -438,7 +442,7 @@ namespace sparta
438442
*/
439443
const value_type & read(const const_reverse_iterator & entry) const
440444
{
441-
return read(entry.base().getIndex_());
445+
return read(std::prev(entry.base()));
442446
}
443447

444448
/**
@@ -465,7 +469,7 @@ namespace sparta
465469
* \param entry the BufferIterator to read from.
466470
*/
467471
value_type & access(const const_reverse_iterator & entry) {
468-
return access(entry.base().getIndex_());
472+
return access(std::prev(entry.base()));
469473
}
470474

471475
/**
@@ -616,10 +620,11 @@ namespace sparta
616620
* a BufferIterator has been created, the
617621
* erase(BufferIterator&) should be used.
618622
*/
619-
void erase(const uint32_t& idx)
623+
void erase(uint32_t idx)
620624
{
621625
// Make sure we are invalidating an already valid object.
622-
sparta_assert(idx < size(), "Cannot erase an index that is not already valid");
626+
sparta_assert(idx < size(),
627+
"Cannot erase an index that is not already valid");
623628

624629
// Do the invalidation immediately
625630
// 1. Move the free space pointer to the erased position.
@@ -634,19 +639,18 @@ namespace sparta
634639
validator_->detachDataPointer(free_position_);
635640

636641
// Shift all the positions above the invalidation in the map one space down.
637-
uint32_t i = idx;
638642
sparta_assert(num_valid_ > 0);
639643
const uint32_t top_idx_of_buffer = num_valid_ - 1;
640-
while(i < top_idx_of_buffer)
644+
while(idx < top_idx_of_buffer)
641645
{
642646
// assert that we are not going to do an invalid read.
643-
sparta_assert(i + 1 < num_entries_);
644-
buffer_map_[i] = buffer_map_[i + 1];
645-
buffer_map_[i]->physical_idx = i;
647+
sparta_assert(idx + 1 < num_entries_);
648+
buffer_map_[idx] = buffer_map_[idx + 1];
649+
buffer_map_[idx]->physical_idx = idx;
646650

647651
// Shift the indexes in the address map.
648-
address_map_[i] = address_map_[i + 1];
649-
++i;
652+
address_map_[idx] = address_map_[idx + 1];
653+
++idx;
650654
}
651655

652656
// the entry at the old num_valid_ in the map now points to nullptr
@@ -664,22 +668,22 @@ namespace sparta
664668
* \brief erase the index at which the entry exists in the Buffer.
665669
* \param entry a reference to the entry to be erased.
666670
*/
667-
void erase(const const_iterator& entry)
671+
iterator erase(const const_iterator& entry)
668672
{
669-
sparta_assert(entry.attached_buffer_ == this, "Cannot erase an entry created by another Buffer");
673+
sparta_assert(entry.attached_buffer_ == this,
674+
"Cannot erase an entry created by another Buffer");
670675
// erase the index in the actual buffer.
671676
erase(entry.getIndex_());
677+
return {this, buffer_map_[entry.getIndex_()]};
672678
}
673679

674680
/**
675681
* \brief erase the index at which the entry exists in the Buffer.
676682
* \param entry a reference to the entry to be erased.
677683
*/
678-
void erase(const const_reverse_iterator& entry)
684+
reverse_iterator erase(const const_reverse_iterator& entry)
679685
{
680-
sparta_assert(entry.base().attached_buffer_ == this, "Cannot erase an entry created by another Buffer");
681-
// erase the index in the actual buffer.
682-
erase(entry.base().getIndex_());
686+
return reverse_iterator{erase(std::prev(entry.base()))};
683687
}
684688

685689
/**
@@ -871,7 +875,8 @@ namespace sparta
871875
void resizeInternalContainers_() {
872876

873877
// Assert that the Buffer class is in Infinite-Mode.
874-
sparta_assert(is_infinite_mode_, "The Buffer class must be in Infinite-Mode in order to resize itself.");
878+
sparta_assert(is_infinite_mode_,
879+
"The Buffer class must be in Infinite-Mode in order to resize itself.");
875880

876881
// We do not resize if there are available slots in buffer.
877882
if(numFree() != 0) {
@@ -998,14 +1003,15 @@ namespace sparta
9981003

9991004
std::string name_;
10001005
const Clock * clk_ = nullptr;
1001-
size_type num_entries_; /*!< The number of entries this buffer can hold */
1002-
PointerList buffer_map_; /*!< A vector list of pointers to all the items active in the buffer */
1003-
size_type data_pool_size_; /*!< The number of elements our data_pool_ can hold*/
1004-
DataPool data_pool_; /*!< A vector twice the size of our Buffer size limit that is filled with pointers for our data.*/
1005-
1006-
DataPointer* free_position_ = 0; /*!< A pointer to a free position in our data_pool_ */
1007-
DataPointer* first_position_ = 0; /*!< A pointer to a first position in our data_pool_; used for lower bound check */
1008-
size_type num_valid_ = 0; /*!< A tally of valid items */
1006+
size_type num_entries_ = 0; /*!< The number of entries this buffer can hold */
1007+
PointerList buffer_map_; /*!< A vector list of pointers to all the items active in the buffer */
1008+
size_type data_pool_size_ = 0; /*!< The number of elements our data_pool_ can hold*/
1009+
DataPool data_pool_; /*!< A vector twice the size of our Buffer size limit
1010+
that is filled with pointers for our data.*/
1011+
1012+
DataPointer* free_position_ = nullptr; /*!< A pointer to a free position in our data_pool_ */
1013+
DataPointer* first_position_ = nullptr; /*!< A pointer to a first position in our data_pool_; used for lower bound check */
1014+
size_type num_valid_ = 0; /*!< A tally of valid items */
10091015
std::unique_ptr<DataPointerValidator> validator_; /*!< Checks the validity of DataPointer */
10101016

10111017
//////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)