@@ -24,9 +24,10 @@ class ChunkedArray {
24
24
public:
25
25
struct Chunk {
26
26
int8_t * data;
27
- // Size holds number of elements, not bytes. Element size
28
- // is determined on push.
29
- size_t size;
27
+ // Max number of elements that can be stored in a chunk. Element type is determined on
28
+ // push when chunk is allocated. Elements of different types shouldn't be pushed into
29
+ // the same chunk.
30
+ size_t max_elems;
30
31
};
31
32
32
33
// Random access iterator to be used with std::nth_element.
@@ -49,15 +50,16 @@ class ChunkedArray {
49
50
if (chunk_idx_ == other.chunk_idx_ ) {
50
51
return chunk_offs_ - other.chunk_offs_ ;
51
52
} else if (chunk_idx_ > other.chunk_idx_ ) {
52
- auto res = (*chunks_)[other.chunk_idx_ ].size - other.chunk_offs_ + chunk_offs_;
53
+ auto res =
54
+ (*chunks_)[other.chunk_idx_ ].max_elems - other.chunk_offs_ + chunk_offs_;
53
55
for (auto i = other.chunk_idx_ + 1 ; i < chunk_idx_; ++i) {
54
- res += (*chunks_)[i].size ;
56
+ res += (*chunks_)[i].max_elems ;
55
57
}
56
58
return (int64_t )res;
57
59
} else {
58
- auto res = (*chunks_)[chunk_idx_].size - chunk_offs_ + other.chunk_offs_ ;
60
+ auto res = (*chunks_)[chunk_idx_].max_elems - chunk_offs_ + other.chunk_offs_ ;
59
61
for (auto i = chunk_idx_ + 1 ; i < other.chunk_idx_ ; ++i) {
60
- res += (*chunks_)[i].size ;
62
+ res += (*chunks_)[i].max_elems ;
61
63
}
62
64
return -(int64_t )res;
63
65
}
@@ -68,7 +70,7 @@ class ChunkedArray {
68
70
operator -=(-i);
69
71
} else {
70
72
while (true ) {
71
- int64_t rem = int64_t ((*chunks_)[chunk_idx_].size - chunk_offs_);
73
+ int64_t rem = int64_t ((*chunks_)[chunk_idx_].max_elems - chunk_offs_);
72
74
if (rem > i) {
73
75
chunk_offs_ += i;
74
76
break ;
@@ -95,7 +97,7 @@ class ChunkedArray {
95
97
while ((int64_t )chunk_offs_ < i) {
96
98
--chunk_idx_;
97
99
i -= chunk_offs_;
98
- chunk_offs_ = (*chunks_)[chunk_idx_].size ;
100
+ chunk_offs_ = (*chunks_)[chunk_idx_].max_elems ;
99
101
}
100
102
chunk_offs_ -= i;
101
103
}
@@ -110,7 +112,7 @@ class ChunkedArray {
110
112
111
113
Iterator& operator ++() {
112
114
++chunk_offs_;
113
- if (chunk_offs_ == (*chunks_)[chunk_idx_].size ) {
115
+ if (chunk_offs_ == (*chunks_)[chunk_idx_].max_elems ) {
114
116
++chunk_idx_;
115
117
chunk_offs_ = 0 ;
116
118
}
@@ -126,7 +128,7 @@ class ChunkedArray {
126
128
Iterator& operator --() {
127
129
if (!chunk_offs_) {
128
130
--chunk_idx_;
129
- chunk_offs_ = (*chunks_)[chunk_idx_].size ;
131
+ chunk_offs_ = (*chunks_)[chunk_idx_].max_elems ;
130
132
}
131
133
--chunk_offs_;
132
134
return *this ;
@@ -177,7 +179,7 @@ class ChunkedArray {
177
179
template <typename T>
178
180
void push (T value) {
179
181
// Check if we need to allocate a new chunk.
180
- if (chunks_.empty () || cur_idx_ == chunks_.back ().size ) {
182
+ if (chunks_.empty () || cur_idx_ == chunks_.back ().max_elems ) {
181
183
// Allocator is most probably a RowSetMemoryOwner object. It is not supposed to be
182
184
// used to allocate very small objects, so we start with 1 KB and double it each
183
185
// time with 64KB limit.
@@ -195,7 +197,7 @@ class ChunkedArray {
195
197
// We are not going to add values to the current last chunk anymore, so fix-up
196
198
// its size for proper iteration.
197
199
if (!chunks_.empty ()) {
198
- chunks_.back ().size = cur_idx_;
200
+ chunks_.back ().max_elems = cur_idx_;
199
201
}
200
202
chunks_.insert (chunks_.end (), other.chunks_ .begin (), other.chunks_ .end ());
201
203
cur_idx_ = other.cur_idx_ ;
@@ -212,7 +214,7 @@ class ChunkedArray {
212
214
// Chunk offset in iterator is always expected to be less than chunk size. So, end
213
215
// iterator for a full chunk is supposed to point the start of the next chunk.
214
216
// Take care of it if all chunks are full.
215
- if (!chunks_.empty () && cur_idx_ == chunks_.back ().size ) {
217
+ if (!chunks_.empty () && cur_idx_ == chunks_.back ().max_elems ) {
216
218
return Iterator<T>(&chunks_, chunks_.size (), 0 );
217
219
}
218
220
return Iterator<T>(&chunks_, chunks_.size () - 1 , cur_idx_);
@@ -227,7 +229,7 @@ class ChunkedArray {
227
229
228
230
size_t res = cur_idx_;
229
231
for (size_t i = 0 ; i < chunks_.size () - 1 ; ++i) {
230
- res += chunks_[i].size ;
232
+ res += chunks_[i].max_elems ;
231
233
}
232
234
return res;
233
235
}
@@ -236,6 +238,8 @@ class ChunkedArray {
236
238
237
239
private:
238
240
SimpleAllocator* allocator_;
241
+ // All chunks except the last one should be full, i.e. they hold
242
+ // chunk.max_elems elements.
239
243
std::vector<Chunk> chunks_;
240
244
// Insertion position in the last chunk.
241
245
size_t cur_idx_;
0 commit comments