Skip to content

Commit f52a9e1

Browse files
committed
- Small optimization in GetRawElement for fixed-size elements
- Made various functions inline to avoid extra function calls
1 parent a997cce commit f52a9e1

1 file changed

Lines changed: 32 additions & 28 deletions

File tree

src/processing/typed_buffer.h

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ ByteBuffer<Codec>::ByteBuffer(
208208
// Initializes `num_elements_` and `offsets_` from the span.
209209
// Called in a lazy manner when the buffer is accessed with GetElement or GetNumElements, avoiding unnecessary initialization.
210210
template <class Codec>
211-
void ByteBuffer<Codec>::InitializeFromSpan() const {
211+
inline void ByteBuffer<Codec>::InitializeFromSpan() const {
212212
if (elements_span_.size() < prefix_size_) {
213213
throw InvalidInputException("Malformed buffer: prefix_size exceeds span size");
214214
}
@@ -265,7 +265,7 @@ void ByteBuffer<Codec>::InitializeFromSpan() const {
265265
}
266266

267267
template <class Codec>
268-
void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
268+
inline void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
269269
// If the span is already initialized, skip it.
270270
if (is_initialized_from_span_) {
271271
return;
@@ -280,7 +280,7 @@ void ByteBuffer<Codec>::EnsureInitializedFromSpan() const {
280280
// For read-only buffers, gets the number of elements in the buffer and sets num_elements_ if not already set.
281281
// A lighter version to only get num_elements_ and avoid calling InitializeFromSpan that also builds offsets_.
282282
template <class Codec>
283-
size_t ByteBuffer<Codec>::GetNumElements() const {
283+
inline size_t ByteBuffer<Codec>::GetNumElements() const {
284284
if (num_elements_ != kUnsetSize) {
285285
return num_elements_;
286286
}
@@ -291,7 +291,7 @@ size_t ByteBuffer<Codec>::GetNumElements() const {
291291
}
292292

293293
template <class Codec>
294-
size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const uint8_t> bytes) {
294+
inline size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const uint8_t> bytes) {
295295
if (bytes.empty())
296296
return 0;
297297

@@ -338,7 +338,7 @@ size_t ByteBuffer<Codec>::EstimateOffsetsReserveCountFromSample(tcb::span<const
338338
// -----------------------------------------------------------------------------
339339

340340
template <class Codec>
341-
size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
341+
inline size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
342342
EnsureInitializedFromSpan();
343343
if (position >= num_elements_) {
344344
throw InvalidInputException("Element position out of range during CalculateOffsetOfElement");
@@ -350,19 +350,23 @@ size_t ByteBuffer<Codec>::CalculateOffsetOfElement(size_t position) const {
350350
}
351351

352352
template <class Codec>
353-
tcb::span<const uint8_t> ByteBuffer<Codec>::GetRawElement(size_t position) const {
353+
inline tcb::span<const uint8_t> ByteBuffer<Codec>::GetRawElement(size_t position) const {
354354
EnsureInitializedFromSpan();
355-
if (position >= num_elements_) {
356-
throw InvalidInputException("Element position out of range during GetRawElement");
357-
}
358-
const size_t offset = CalculateOffsetOfElement(position);
359355

360356
// For fixed-size elements are stored contiguously.
361357
if constexpr (is_fixed_sized) {
358+
if (position >= num_elements_) {
359+
throw InvalidInputException("Element position out of range during GetRawElement");
360+
}
361+
const size_t offset = prefix_size_ + (position * element_size_);
362362
return elements_span_.subspan(offset, element_size_);
363363
}
364364

365365
// For variable-size elements, we need to read the size first [u32 size][element].
366+
if (position >= num_elements_) {
367+
throw InvalidInputException("Element position out of range during GetRawElement");
368+
}
369+
const size_t offset = offsets_[position];
366370
if (offset == kUnsetSize) {
367371
throw InvalidInputException("Element position has not been written yet");
368372
}
@@ -371,7 +375,7 @@ tcb::span<const uint8_t> ByteBuffer<Codec>::GetRawElement(size_t position) const
371375
}
372376

373377
template <class Codec>
374-
typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t position) const {
378+
inline typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t position) const {
375379
return codec_.Decode(GetRawElement(position));
376380
}
377381

@@ -384,7 +388,7 @@ typename ByteBuffer<Codec>::value_type ByteBuffer<Codec>::GetElement(size_t posi
384388
// -----------------------------------------------------------------------------
385389

386390
template <class Codec>
387-
ByteBuffer<Codec>::ConstIterator::ConstIterator(const ByteBuffer<Codec>* buffer, size_t cursor_offset)
391+
inline ByteBuffer<Codec>::ConstIterator::ConstIterator(const ByteBuffer<Codec>* buffer, size_t cursor_offset)
388392
: buffer_(buffer),
389393
cursor_offset_(cursor_offset),
390394
elements_span_size_(buffer != nullptr ? buffer->elements_span_.size() : 0u),
@@ -416,7 +420,7 @@ inline size_t ByteBuffer<Codec>::ConstIterator::ReadAndValidateVariableElementSi
416420
}
417421

418422
template <class Codec>
419-
tcb::span<const uint8_t> ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() const {
423+
inline tcb::span<const uint8_t> ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() const {
420424
if (buffer_ == nullptr || cursor_offset_ >= elements_span_size_) {
421425
throw InvalidInputException("Cannot dereference ByteBuffer iterator at end position");
422426
}
@@ -429,14 +433,14 @@ tcb::span<const uint8_t> ByteBuffer<Codec>::ConstIterator::RawSpanAtCursor() con
429433
}
430434

431435
template <class Codec>
432-
typename ByteBuffer<Codec>::ConstIterator::value_type ByteBuffer<Codec>::ConstIterator::operator*() const {
436+
inline typename ByteBuffer<Codec>::ConstIterator::value_type ByteBuffer<Codec>::ConstIterator::operator*() const {
433437
// Decode converts raw bytes into the codec's value_type (e.g. int32_t, float, string_view).
434438
// This keeps the iterator's return type consistent with GetElement across all codecs.
435439
return buffer_->codec_.Decode(RawSpanAtCursor());
436440
}
437441

438442
template <class Codec>
439-
typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::operator++() {
443+
inline typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::operator++() {
440444
if (buffer_ == nullptr || cursor_offset_ >= elements_span_size_) {
441445
return *this;
442446
}
@@ -451,23 +455,23 @@ typename ByteBuffer<Codec>::ConstIterator& ByteBuffer<Codec>::ConstIterator::ope
451455
}
452456

453457
template <class Codec>
454-
bool ByteBuffer<Codec>::ConstIterator::operator==(const ConstIterator& other) const {
458+
inline bool ByteBuffer<Codec>::ConstIterator::operator==(const ConstIterator& other) const {
455459
return buffer_ == other.buffer_ && cursor_offset_ == other.cursor_offset_;
456460
}
457461

458462
template <class Codec>
459-
bool ByteBuffer<Codec>::ConstIterator::operator!=(const ConstIterator& other) const {
463+
inline bool ByteBuffer<Codec>::ConstIterator::operator!=(const ConstIterator& other) const {
460464
return !(*this == other);
461465
}
462466

463467
template <class Codec>
464-
tcb::span<const uint8_t> ByteBuffer<Codec>::ConstRawIterator::operator*() const {
468+
inline tcb::span<const uint8_t> ByteBuffer<Codec>::ConstRawIterator::operator*() const {
465469
// Returns the raw bytes for the current element, consistent with GetRawElement.
466470
return this->RawSpanAtCursor();
467471
}
468472

469473
template <class Codec>
470-
void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
474+
inline void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
471475
if (is_write_buffer_initialized_) {
472476
throw InvalidInputException("Iterator is only available for read buffers");
473477
}
@@ -486,19 +490,19 @@ void ByteBuffer<Codec>::ValidateIteratorReadPreconditions() const {
486490
}
487491

488492
template <class Codec>
489-
typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::begin() const {
493+
inline typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::begin() const {
490494
ValidateIteratorReadPreconditions();
491495
return ConstIterator(this, prefix_size_);
492496
}
493497

494498
template <class Codec>
495-
typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::end() const {
499+
inline typename ByteBuffer<Codec>::ConstIterator ByteBuffer<Codec>::end() const {
496500
ValidateIteratorReadPreconditions();
497501
return ConstIterator(this, elements_span_.size());
498502
}
499503

500504
template <class Codec>
501-
typename ByteBuffer<Codec>::RawElementsView ByteBuffer<Codec>::raw_elements() const {
505+
inline typename ByteBuffer<Codec>::RawElementsView ByteBuffer<Codec>::raw_elements() const {
502506
ValidateIteratorReadPreconditions();
503507
return RawElementsView{this};
504508
}
@@ -540,7 +544,7 @@ ByteBuffer<Codec>::ByteBuffer(
540544

541545
// Initializes `write_buffer_`, `offsets_` and `elements_span_`
542546
template <class Codec>
543-
void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_bytes_hint) {
547+
inline void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_bytes_hint) {
544548
// Fixed-size elements
545549
if constexpr (is_fixed_sized) {
546550
if (element_size_ <= 0) {
@@ -592,7 +596,7 @@ void ByteBuffer<Codec>::InitializeForWriteBuffer(size_t variable_size_reserved_b
592596

593597

594598
template <class Codec>
595-
tcb::span<uint8_t> ByteBuffer<Codec>::GetWritableSpanForElement(size_t position, size_t payload_size) {
599+
inline tcb::span<uint8_t> ByteBuffer<Codec>::GetWritableSpanForElement(size_t position, size_t payload_size) {
596600
if (!is_write_buffer_initialized_) {
597601
throw InvalidInputException("Cannot GetWriteSpanForElement: write buffer is not initialized.");
598602
}
@@ -651,7 +655,7 @@ tcb::span<uint8_t> ByteBuffer<Codec>::GetWritableSpanForElement(size_t position,
651655
}
652656

653657
template <class Codec>
654-
void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
658+
inline void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
655659
if constexpr (is_fixed_sized) {
656660
auto write_span = GetWritableSpanForElement(position, element_size_);
657661
codec_.Encode(element, write_span);
@@ -662,13 +666,13 @@ void ByteBuffer<Codec>::SetElement(size_t position, const value_type& element) {
662666
}
663667

664668
template <class Codec>
665-
void ByteBuffer<Codec>::SetRawElement(size_t position, tcb::span<const uint8_t> raw) {
669+
inline void ByteBuffer<Codec>::SetRawElement(size_t position, tcb::span<const uint8_t> raw) {
666670
auto write_span = GetWritableSpanForElement(position, raw.size());
667671
std::memcpy(write_span.data(), raw.data(), raw.size());
668672
}
669673

670674
template <class Codec>
671-
std::vector<uint8_t> ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
675+
inline std::vector<uint8_t> ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
672676
if (is_write_buffer_finalized_) {
673677
throw InvalidInputException("FinalizeAndTakeBuffer: write buffer has already been finalized");
674678
}
@@ -739,7 +743,7 @@ std::vector<uint8_t> ByteBuffer<Codec>::FinalizeAndTakeBuffer() {
739743
}
740744

741745
template <class Codec>
742-
void ByteBuffer<Codec>::RebindSpanToWriteBuffer() {
746+
inline void ByteBuffer<Codec>::RebindSpanToWriteBuffer() {
743747
elements_span_ = tcb::span<const uint8_t>(write_buffer_.data(), write_buffer_.size());
744748
}
745749

0 commit comments

Comments
 (0)