2222#include < array>
2323#include < memory>
2424
25- // Basically equivalent to std::vector, but without the edge case for booleans,
26- // i.e. data() returns T* for all T. This allows for implicit conversion to
27- // std::span for all T.
28-
2925namespace facebook ::nimble {
3026
27+ // / A vector-like container similar to std::vector, but without the edge case
28+ // / for booleans. Unlike std::vector<bool>, data() returns T* for all T,
29+ // / allowing implicit conversion to std::span for all T.
3130template <typename T>
3231class Vector {
3332 using InnerType =
3433 typename std::conditional<std::is_same_v<T, bool >, uint8_t , T>::type;
3534
3635 public:
37- Vector (velox::memory::MemoryPool* memoryPool, size_t size, T value)
38- : memoryPool_{memoryPool } {
36+ // / Constructs a vector with the given size, filled with the specified value.
37+ Vector (velox::memory::MemoryPool* pool, size_t size, T value) : pool_{pool } {
3938 init (size);
4039 std::fill (dataRawPtr_, dataRawPtr_ + size_, value);
4140 }
4241
43- Vector (velox::memory::MemoryPool* memoryPool, size_t size)
44- : memoryPool_{memoryPool } {
42+ // / Constructs a vector with the given size, with uninitialized elements.
43+ Vector (velox::memory::MemoryPool* pool, size_t size) : pool_{pool } {
4544 init (size);
4645 }
4746
48- explicit Vector (velox::memory::MemoryPool* memoryPool)
49- : memoryPool_{memoryPool } {
47+ // / Constructs an empty vector.
48+ explicit Vector (velox::memory::MemoryPool* pool) : pool_{pool } {
5049 capacity_ = 0 ;
5150 size_ = 0 ;
5251 data_ = nullptr ;
@@ -56,33 +55,37 @@ class Vector {
5655#endif
5756 }
5857
58+ // / Constructs a vector from an iterator range.
5959 template <typename It>
60- Vector (velox::memory::MemoryPool* memoryPool, It first, It last)
61- : memoryPool_{memoryPool} {
60+ Vector (velox::memory::MemoryPool* pool, It first, It last) : pool_{pool} {
6261 auto size = last - first;
6362 init (size);
6463 std::copy (first, last, dataRawPtr_);
6564 }
6665
66+ // / Copy constructor.
6767 Vector (const Vector& other) {
6868 *this = other;
6969 }
7070
71+ // / Copy assignment operator.
7172 Vector& operator =(const Vector& other) {
7273 if (this != &other) {
7374 size_ = other.size ();
7475 capacity_ = other.capacity_ ;
75- memoryPool_ = other.memoryPool_ ;
76+ pool_ = other.pool_ ;
7677 allocateBuffer ();
7778 std::copy (other.dataRawPtr_ , other.dataRawPtr_ + size_, dataRawPtr_);
7879 }
7980 return *this ;
8081 }
8182
83+ // / Move constructor.
8284 Vector (Vector&& other) noexcept {
8385 *this = std::move (other);
8486 }
8587
88+ // / Move assignment operator.
8689 Vector& operator =(Vector&& other) noexcept {
8790 if (this != &other) {
8891 size_ = other.size ();
@@ -94,81 +97,106 @@ class Vector {
9497 if (data_ != nullptr ) {
9598 dataRawPtr_ = reinterpret_cast <T*>(data_->asMutable <InnerType>());
9699 }
97- memoryPool_ = other.memoryPool_ ;
100+ pool_ = other.pool_ ;
98101 other.size_ = 0 ;
99102 other.capacity_ = 0 ;
100103 }
101104 return *this ;
102105 }
103106
104- Vector (velox::memory::MemoryPool* memoryPool, std::initializer_list<T> l)
105- : memoryPool_{memoryPool} {
107+ // / Constructs a vector from an initializer list.
108+ Vector (velox::memory::MemoryPool* pool, std::initializer_list<T> l)
109+ : pool_{pool} {
106110 init (l.size ());
107111 std::copy (l.begin (), l.end (), dataRawPtr_);
108112 }
109113
110- inline velox::memory::MemoryPool* memoryPool () {
111- return memoryPool_;
114+ // / Returns the memory pool used by this vector.
115+ inline velox::memory::MemoryPool* pool () {
116+ return pool_;
112117 }
113118
119+ // / Returns the number of elements in the vector.
114120 uint64_t size () const {
115121 return size_;
116122 }
123+
124+ // / Returns true if the vector is empty.
117125 bool empty () const {
118126 return size_ == 0 ;
119127 }
128+
129+ // / Returns the current capacity of the vector.
120130 uint64_t capacity () const {
121131 return capacity_;
122132 }
133+ // / Returns a reference to the element at the given index.
123134 T& operator [](uint64_t i) {
124135 return dataRawPtr_[i];
125136 }
137+
138+ // / Returns a const reference to the element at the given index.
126139 const T& operator [](uint64_t i) const {
127140 return dataRawPtr_[i];
128141 }
142+
143+ // / Returns a pointer to the first element.
129144 T* begin () {
130145 return dataRawPtr_;
131146 }
147+
148+ // / Returns a pointer past the last element.
132149 T* end () {
133150 return dataRawPtr_ + size_;
134151 }
152+
153+ // / Returns a const pointer to the first element.
135154 const T* begin () const {
136155 return dataRawPtr_;
137156 }
157+
158+ // / Returns a const pointer past the last element.
138159 const T* end () const {
139160 return dataRawPtr_ + size_;
140161 }
162+
163+ // / Returns a reference to the last element.
141164 T& back () {
142165 return dataRawPtr_[size_ - 1 ];
143166 }
167+
168+ // / Returns a const reference to the last element.
144169 const T& back () const {
145170 return dataRawPtr_[size_ - 1 ];
146171 }
147172
148- // Directly updates the size_ to |size|. Useful if you've filled in some data
149- // directly using the underlying raw pointers.
173+ // / Directly updates the size to the given value.
174+ // / Useful if you've filled in data directly using the underlying raw
175+ // / pointers.
150176 void update_size (uint64_t size) {
151177 size_ = size;
152178 }
153179
154- // Fills all of data_ with T().
180+ // / Fills all elements with the default value T().
155181 void zero_out () {
156182 std::fill (dataRawPtr_, dataRawPtr_ + size_, T ());
157183 }
158184
159- // Fills all of data_ with the given value.
185+ // / Fills all elements with the given value.
160186 void fill (T value) {
161187 std::fill (dataRawPtr_, dataRawPtr_ + size_, value);
162188 }
163189
164- // Resets *this to a newly constructed empty state.
190+ // / Resets the vector to an empty state, releasing allocated memory .
165191 void clear () {
166192 capacity_ = 0 ;
167193 size_ = 0 ;
168194 data_.reset ();
169195 dataRawPtr_ = nullptr ;
170196 }
171197
198+ // / Inserts elements from [inputStart, inputEnd) at the given output
199+ // / position.
172200 void insert (T* output, const T* inputStart, const T* inputEnd) {
173201 const uint64_t inputSize = inputEnd - inputStart;
174202 const uint64_t distanceToEnd = end () - output;
@@ -182,21 +210,24 @@ class Vector {
182210 }
183211 }
184212
185- // Add |copies| copies of | value| to the end of the vector.
213+ // / Appends the given number of copies of value to the end of the vector.
186214 void extend (uint64_t copies, T value) {
187215 reserve (size_ + copies);
188216 std::fill (end (), end () + copies, value);
189217 size_ += copies;
190218 }
191219
220+ // / Returns a pointer to the underlying data.
192221 T* data () noexcept {
193222 return dataRawPtr_;
194223 }
195224
225+ // / Returns a const pointer to the underlying data.
196226 const T* data () const noexcept {
197227 return dataRawPtr_;
198228 }
199229
230+ // / Appends the given value to the end of the vector.
200231 void push_back (T value) {
201232 if (size_ == capacity_) {
202233 reserve (calculateNewSize (capacity_));
@@ -205,6 +236,7 @@ class Vector {
205236 ++size_;
206237 }
207238
239+ // / Constructs an element in-place at the end of the vector.
208240 template <typename ... Args>
209241 void emplace_back (Args&&... args) {
210242 if (size_ == capacity_) {
@@ -215,13 +247,13 @@ class Vector {
215247 ++size_;
216248 }
217249
218- // Ensures that *this can hold |size| elements. Does NOT shrink to
219- // fit if | size| is less than size() , and does NOT initialize any new
220- // values .
250+ // / Ensures the vector can hold at least the given number of elements.
251+ // / Does NOT shrink if size is less than current size, and does NOT
252+ // / initialize any new elements .
221253 void reserve (uint64_t size) {
222254 if (size > capacity_) {
223255 auto newData =
224- velox::AlignedBuffer::allocateExact<InnerType>(size, memoryPool_ );
256+ velox::AlignedBuffer::allocateExact<InnerType>(size, pool_ );
225257 // AlignedBuffer can allocate a bit more than requested for the alignment
226258 // purpose, let's leverage that by using its true capacity.
227259 capacity_ = newData->capacity () / sizeof (InnerType);
@@ -238,15 +270,15 @@ class Vector {
238270 }
239271 }
240272
241- // Changes size_ to | size|. Does NOT shrink to fit the new size, and
242- // does NOT initialize any new elements if |size| is greater than size_ .
273+ // / Changes the size of the vector.
274+ // / Does NOT shrink capacity, and does NOT initialize new elements .
243275 void resize (uint64_t size) {
244276 reserve (size);
245277 size_ = size;
246278 }
247279
248- // Changes size_ to |newSize|. Does NOT shrink to fit the new size. Initialize
249- // any new elements to |value| if |newSize| is greater than size_ .
280+ // / Changes the size of the vector, initializing new elements to value.
281+ // / Does NOT shrink capacity .
250282 void resize (uint64_t newSize, const T& value) {
251283 auto initialSize = size_;
252284 resize (newSize);
@@ -256,6 +288,8 @@ class Vector {
256288 }
257289 }
258290
291+ // / Releases ownership of the underlying buffer and returns it.
292+ // / The vector is left in an empty state after this call.
259293 velox::BufferPtr releaseOwnership () {
260294 velox::BufferPtr tmp = std::move (data_);
261295 tmp->setSize (size_);
@@ -286,16 +320,15 @@ class Vector {
286320 }
287321
288322 inline void allocateBuffer () {
289- data_ =
290- velox::AlignedBuffer::allocateExact<InnerType>(capacity_, memoryPool_);
323+ data_ = velox::AlignedBuffer::allocateExact<InnerType>(capacity_, pool_);
291324 dataRawPtr_ = reinterpret_cast <T*>(data_->asMutable <InnerType>());
292325 uint64_t newCapacity = data_->capacity () / sizeof (InnerType);
293326 NIMBLE_DCHECK_GE (
294327 newCapacity, capacity_, " Allocated capacity is smaller than requested" );
295328 capacity_ = newCapacity;
296329 }
297330
298- velox::memory::MemoryPool* memoryPool_ ;
331+ velox::memory::MemoryPool* pool_ ;
299332 velox::BufferPtr data_;
300333 uint64_t capacity_;
301334 uint64_t size_;
0 commit comments