2525#include " olap/types.h"
2626#include " util/coding.h"
2727#include " util/faststring.h"
28+ #include " vec/common/unaligned.h"
2829
2930namespace doris {
3031#include " common/compile_check_begin.h"
@@ -33,32 +34,36 @@ namespace segment_v2 {
3334static const size_t PLAIN_PAGE_HEADER_SIZE = sizeof (uint32_t );
3435
3536template <FieldType Type>
36- class PlainPageBuilder : public PageBuilderHelper <PlainPageBuilder<Type> > {
37+ class PlainPageBuilder : public PageBuilderHelper <PlainPageBuilder<Type>> {
3738public:
3839 using Self = PlainPageBuilder<Type>;
3940 friend class PageBuilderHelper <Self>;
4041
4142 Status init () override {
4243 // Reserve enough space for the page, plus a bit of slop since
4344 // we often overrun the page by a few values.
44- RETURN_IF_CATCH_EXCEPTION (_buffer.reserve (_options.data_page_size + 1024 ));
45+ RETURN_IF_CATCH_EXCEPTION (_buffer.reserve (_options.data_page_size ));
4546 return reset ();
4647 }
4748
48- bool is_page_full () override { return _buffer. size () > _options. data_page_size ; }
49+ bool is_page_full () override { return _remain_element_capacity == 0 ; }
4950
5051 Status add (const uint8_t * vals, size_t * count) override {
51- if (is_page_full ()) {
52+ if (is_page_full () || *count == 0 ) {
5253 *count = 0 ;
5354 return Status::OK ();
5455 }
5556 size_t old_size = _buffer.size ();
57+ size_t to_add = std::min (_remain_element_capacity, *count);
5658 // This may need a large memory, should return error if could not allocated
5759 // successfully, to avoid BE OOM.
58- RETURN_IF_CATCH_EXCEPTION (_buffer.resize (old_size + *count * SIZE_OF_TYPE));
59- memcpy (&_buffer[old_size], vals, *count * SIZE_OF_TYPE);
60- _count += *count;
61- _raw_data_size += *count * SIZE_OF_TYPE;
60+ RETURN_IF_CATCH_EXCEPTION (_buffer.resize (old_size + to_add * SIZE_OF_TYPE));
61+ memcpy (&_buffer[old_size], vals, to_add * SIZE_OF_TYPE);
62+ _count += to_add;
63+ _raw_data_size += to_add * SIZE_OF_TYPE;
64+
65+ *count = to_add;
66+ _remain_element_capacity -= to_add;
6267 return Status::OK ();
6368 }
6469
@@ -78,11 +83,12 @@ class PlainPageBuilder : public PageBuilderHelper<PlainPageBuilder<Type> > {
7883
7984 Status reset () override {
8085 RETURN_IF_CATCH_EXCEPTION ({
81- _buffer.reserve (_options.data_page_size + 1024 );
86+ _buffer.reserve (_options.data_page_size );
8287 _count = 0 ;
8388 _raw_data_size = 0 ;
8489 _buffer.clear ();
8590 _buffer.resize (PLAIN_PAGE_HEADER_SIZE);
91+ _remain_element_capacity = _options.data_page_size / SIZE_OF_TYPE;
8692 });
8793 return Status::OK ();
8894 }
@@ -115,6 +121,7 @@ class PlainPageBuilder : public PageBuilderHelper<PlainPageBuilder<Type> > {
115121 faststring _buffer;
116122 PageBuilderOptions _options;
117123 size_t _count;
124+ size_t _remain_element_capacity {0 };
118125 uint64_t _raw_data_size = 0 ;
119126 typedef typename TypeTraits<Type>::CppType CppType;
120127 enum { SIZE_OF_TYPE = TypeTraits<Type>::size };
@@ -204,7 +211,48 @@ class PlainPageDecoder : public PageDecoder {
204211 }
205212
206213 Status next_batch (size_t * n, vectorized::MutableColumnPtr& dst) override {
207- return Status::NotSupported (" plain page not implement vec op now" );
214+ DCHECK (_parsed);
215+ if (*n == 0 || _cur_idx >= _num_elems) [[unlikely]] {
216+ return Status::OK ();
217+ }
218+
219+ size_t max_fetch = std::min (*n, static_cast <size_t >(_num_elems - _cur_idx));
220+ const void * src_data = &_data[PLAIN_PAGE_HEADER_SIZE + _cur_idx * SIZE_OF_TYPE];
221+
222+ dst->insert_many_fix_len_data ((const char *)src_data, max_fetch);
223+
224+ *n = max_fetch;
225+ _cur_idx += max_fetch;
226+
227+ return Status::OK ();
228+ }
229+
230+ Status read_by_rowids (const rowid_t * rowids, ordinal_t page_first_ordinal, size_t * n,
231+ vectorized::MutableColumnPtr& dst) override {
232+ DCHECK (_parsed);
233+ if (*n == 0 ) [[unlikely]] {
234+ return Status::OK ();
235+ }
236+
237+ auto total = *n;
238+ auto read_count = 0 ;
239+ _buffer.resize (total);
240+ for (size_t i = 0 ; i < total; ++i) {
241+ ordinal_t ord = rowids[i] - page_first_ordinal;
242+ if (UNLIKELY (ord >= _num_elems)) {
243+ break ;
244+ }
245+
246+ _buffer[read_count++] =
247+ unaligned_load<CppType>(&_data[PLAIN_PAGE_HEADER_SIZE + ord * SIZE_OF_TYPE]);
248+ }
249+
250+ if (LIKELY (read_count > 0 )) {
251+ dst->insert_many_fix_len_data ((char *)_buffer.data (), read_count);
252+ }
253+
254+ *n = read_count;
255+ return Status::OK ();
208256 }
209257
210258 size_t count () const override {
@@ -225,6 +273,8 @@ class PlainPageDecoder : public PageDecoder {
225273 uint32_t _cur_idx;
226274 typedef typename TypeTraits<Type>::CppType CppType;
227275 enum { SIZE_OF_TYPE = TypeTraits<Type>::size };
276+
277+ std::vector<std::conditional_t <std::is_same_v<CppType, bool >, uint8_t , CppType>> _buffer;
228278};
229279
230280} // namespace segment_v2
0 commit comments