Skip to content

Commit

Permalink
Buffers optimisation
Browse files Browse the repository at this point in the history
  • Loading branch information
paveldn committed Mar 20, 2024
1 parent 3c7780e commit 60a0767
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 64 deletions.
94 changes: 71 additions & 23 deletions include/utils/circular_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,47 @@ class CircularBuffer
~CircularBuffer() noexcept;
CircularBuffer& operator=(const CircularBuffer& source);
const T& operator[] (size_t index) const;
size_t get_capacity() const { return size_; };
size_t get_available() const { return head_ <= tail_ ? tail_ - head_ : size_ - head_ + tail_; };
size_t get_capacity() const { return capacity_; };
size_t get_size() const;
size_t get_space() const { return this->capacity_ - this->get_size(); };
size_t push(const T& item);
size_t push(const T* items, size_t size);
size_t pop(T* items, size_t size);
T* reserve(size_t& size);
void clear();
size_t drop(size_t size);
bool empty() const { return head_ == tail_; };
bool empty() const { return is_empty_; };
private:
size_t size_;
bool is_empty_;
size_t capacity_;
T* buffer_;
size_t head_;
size_t tail_;
};

template<class T>
CircularBuffer<T>::CircularBuffer(size_t capacity) :
size_(capacity < CIRCULAR_BUFFER_MINIMUM_SIZE ? CIRCULAR_BUFFER_MINIMUM_SIZE : capacity),
buffer_(new T[size_]),
is_empty_(true),
capacity_(capacity < CIRCULAR_BUFFER_MINIMUM_SIZE ? CIRCULAR_BUFFER_MINIMUM_SIZE : capacity),
buffer_(new T[capacity_]),
head_(0),
tail_(0)
{}

template<class T>
CircularBuffer<T>::CircularBuffer(const CircularBuffer& source) :
size_(source.size_),
buffer_(new T[size_]),
is_empty_(source.is_empty_),
capacity_(source.capacity_),
buffer_(new T[capacity_]),
head_(source.head_),
tail_(source.tail_)
{
for (size_t i = this->head_; i < this->tail_; i++)
this->buffer_[i] = source.buffer_[i];
size_t size = source.get_size();
for (size_t i = 0; i < size; i++)
{
size_t ind = (this->head_ + i) % this->capacity_;
this->buffer_[ind] = source.buffer_[ind];
}
}

template<class T>
Expand All @@ -60,29 +69,42 @@ CircularBuffer<T>& CircularBuffer<T>::operator=(const CircularBuffer& source)
if (this != &source)
{
delete[] this->buffer_;
this->size_ = source.size_;
this->buffer_ = new T[this->size_];
this->capacity_ = source.capacity_;
this->buffer_ = new T[this->capacity_];
this->head_ = source.head_;
this->tail_ = source.tail_;
for (size_t i = this->head_; i < this->tail_; i++)
this->buffer_[i] = source.buffer_[i];
size_t size = source.get_size();
for (size_t i = 0; i < size; i++)
{
size_t ind = (this->head_ + i) % this->capacity_;
this->buffer_[ind] = source.buffer_[ind];
}
}
return *this;
}

template<class T>
const T& CircularBuffer<T>::operator[] (size_t index) const
{
return this->buffer_[(this->head_ + index) % this->size_];
return this->buffer_[(this->head_ + index) % this->capacity_];
}

template<class T>
size_t CircularBuffer<T>::get_size() const
{
if (this->tail_ == this->head_)
return this->is_empty_ ? 0 : this->capacity_;
return this->head_ < this->tail_ ? this->tail_ - this->head_ : this->capacity_ - this->head_ + this->tail_;
}

template<class T>
size_t CircularBuffer<T>::push(const T& item)
{
if ((this->tail_ + 1) % this->size_ != this->head_)
if (this->is_empty_ || (this->tail_ != this->head_))
{
this->buffer_[this->tail_] = item;
this->tail_ = (this->tail_ + 1) % this->size_;
this->tail_ = (this->tail_ + 1) % this->capacity_;
this->is_empty_ = false;
return 1;
}
return 0;
Expand All @@ -91,45 +113,71 @@ size_t CircularBuffer<T>::push(const T& item)
template<class T>
size_t CircularBuffer<T>::push(const T* items, size_t size)
{
size_t size_to_push = (int)(this->size_ - this->get_available());
size_t size_to_push = this->get_space();
if (size_to_push > size)
size_to_push = size;
for (size_t i = 0; i < size_to_push; i++)
{
this->buffer_[tail_] = items[i];
this->tail_ = (this->tail_ + 1) % this->size_;
this->tail_ = (this->tail_ + 1) % this->capacity_;
}
if (size_to_push > 0)
this->is_empty_ = false;
return size_to_push;
}

template<class T>
size_t CircularBuffer<T>::pop(T* items, size_t size)
{
size_t pop_size = this->get_available();
size_t sz = this->get_size();
size_t pop_size = sz;
if (size < pop_size)
pop_size = size;
for (size_t i = 0; i < pop_size; i++)
{
items[i] = this->buffer_[this->head_];
this->head_ = (this->head_ + 1) % this->size_;
this->head_ = (this->head_ + 1) % this->capacity_;
}
if (pop_size == sz)
this->is_empty_ = true;
return pop_size;
}

template<class T>
T* CircularBuffer<T>::reserve(size_t& size)
{
size_t new_size;
size_t head = this->head_ == 0 ? this->capacity_ : 0;
if (head > this->tail_)
new_size = std::min(size, head - this->tail_);
else
new_size = std::min(size, this->capacity_ - this->tail_);
T* result = this->buffer_ + this->tail_;
this->tail_ = (this->tail_ + new_size) % this->capacity_;
size = new_size;
if (new_size > 0)
this->is_empty_ = false;
return result;
}

template<class T>
void CircularBuffer<T>::clear()
{
this->is_empty_ = true;
this->head_ = 0;
this->tail_ = 0;
}

template<class T>
size_t CircularBuffer<T>::drop(size_t size)
{
size_t drop_size = this->get_available();
size_t sz = this->get_size();
size_t drop_size = sz;
if (size < drop_size)
drop_size = size;
this->head_ = (this->head_ + drop_size) % this->size_;
this->head_ = (this->head_ + drop_size) % this->capacity_;
if (drop_size == sz)
this->is_empty_ = true;;
return drop_size;
}

Expand Down
37 changes: 11 additions & 26 deletions include/utils/haier_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,38 @@ extern const char hex_map[];

#if (HAIER_LOG_LEVEL > 0)
#define HAIER_LOGE(...) log_haier(haier_protocol::HaierLogLevel::LEVEL_ERROR, __VA_ARGS__)
#define HAIER_BUFE(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_ERROR, header, buffer, size)
#else
#define HAIER_LOGE(...)
#define HAIER_BUFE(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 1)
#define HAIER_LOGW(...) log_haier(haier_protocol::HaierLogLevel::LEVEL_WARNING, __VA_ARGS__)
#define HAIER_BUFW(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_WARNING, header, buffer, size)
#else
#define HAIER_LOGW(...)
#define HAIER_BUFW(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 2)
#define HAIER_LOGI(...) log_haier(haier_protocol::HaierLogLevel::LEVEL_INFO, __VA_ARGS__)
#define HAIER_BUFI(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_INFO, header, buffer, size)
#else
#define HAIER_LOGI(...)
#define HAIER_BUFI(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 3)
#define HAIER_LOGD(...) log_haier(haier_protocol::HaierLogLevel::LEVEL_DEBUG, __VA_ARGS__)
#define HAIER_BUFD(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_DEBUG, header, buffer, size)
#else
#define HAIER_LOGD(...)
#define HAIER_BUFD(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 4)
#define HAIER_LOGV(...) log_haier(haier_protocol::HaierLogLevel::LEVEL_VERBOSE, __VA_ARGS__)
#define HAIER_BUFV(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_VERBOSE, header, buffer, size)
#else
#define HAIER_LOGV(...)
#endif

#if (HAIER_LOG_LEVEL > 0)
#define HAIER_BUFE(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_ERROR, header, buffer, size)
#else
#define HAIER_BUFE(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 1)
#define HAIER_BUFW(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_WARNING, header, buffer, size)
#else
#define HAIER_BUFW(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 2)
#define HAIER_BUFI(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_INFO, header, buffer, size)
#else
#define HAIER_BUFI(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 3)
#define HAIER_BUFD(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_DEBUG, header, buffer, size)
#else
#define HAIER_BUFD(header, buffer, size)
#endif
#if (HAIER_LOG_LEVEL > 4)
#define HAIER_BUFV(header, buffer, size) log_haier_buffer(haier_protocol::HaierLogLevel::LEVEL_VERBOSE, header, buffer, size)
#else
#define HAIER_BUFV(header, buffer, size)
#define HAIER_BUFV(header, buffer, size)
#endif

std::string buf_to_hex(const uint8_t* message, size_t size);
Expand All @@ -81,6 +65,7 @@ using LogHandler = std::function<void(HaierLogLevel, const char*, const char*)>;

size_t log_haier(HaierLogLevel level, const char* format, ...);
size_t log_haier_buffer(HaierLogLevel level, const char* header, const uint8_t* buffer, size_t size);
size_t log_haier_buffers(HaierLogLevel level, const char* header, const uint8_t* buffer1, size_t size1, const uint8_t* buffer2, size_t size2);
void set_log_handler(LogHandler);
void reset_log_handler();

Expand Down
55 changes: 48 additions & 7 deletions src/transport/protocol_transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,47 @@ uint8_t TransportLevelHandler::send_data(uint8_t frame_type, const uint8_t *data
return (uint8_t)size;
}

size_t TransportLevelHandler::read_data()
{
size_t count = this->stream_.available();
if (count >= this->buffer_.get_capacity())
count = this->buffer_.get_capacity();
// Need to make space
size_t available = this->buffer_.get_space();
if (count > available)
{
this->drop_bytes_(count - available);
if (this->frame_start_found_)
{
// Resetting frame because we will lose it start
HAIER_LOGW("Frame lost because of buffer overflow");
this->pos_ = 0;
this->sep_count_ = 0;
this->frame_start_found_ = false;
this->current_frame_.reset();
}
}
size_t size1 = count;
size_t size2 = 0;
uint8_t *buf1 = this->buffer_.reserve(size1);
uint8_t *buf2 = nullptr;
size1 = this->stream_.read_array(buf1, size1);
if (count > size1)
{
size2 = count - size1;
buf2 = this->buffer_.reserve(size2);
size2 = this->stream_.read_array(buf2, size2);
}
#if (HAIER_LOG_LEVEL > 4)
if (size1 + size2 > 0)
{
log_haier_buffers(haier_protocol::HaierLogLevel::LEVEL_VERBOSE, "Received data:", buf1, size1, buf2, size2);
}
#endif
return size1 + size2;
}

#if 0
size_t TransportLevelHandler::read_data()
{
size_t bytes_read = 0;
Expand All @@ -50,7 +91,6 @@ size_t TransportLevelHandler::read_data()
#if (HAIER_LOG_LEVEL > 4)
out_buf[bytes_read] = val;
#endif
// IF there is 0xFF 0x55 replace it with 0xFF
if (this->buffer_.push(val) == 0)
break;
bytes_read++;
Expand All @@ -63,6 +103,7 @@ size_t TransportLevelHandler::read_data()
#endif
return bytes_read;
}
#endif

void TransportLevelHandler::process_data()
{
Expand All @@ -82,7 +123,7 @@ void TransportLevelHandler::process_data()
}
if (!this->buffer_.empty())
{
size_t buf_size = this->buffer_.get_available();
size_t buf_size = this->buffer_.get_size();
int bytes_to_drop = 0;
while (this->pos_ < buf_size)
{
Expand Down Expand Up @@ -147,7 +188,7 @@ void TransportLevelHandler::process_data()
this->current_frame_.reset();
pos_ = 0;
sep_count_ = 0;
buf_size = buffer_.get_available();
buf_size = buffer_.get_size();
frame_start_found_ = false;
continue;
}
Expand Down Expand Up @@ -192,7 +233,7 @@ void TransportLevelHandler::process_data()
this->current_frame_.reset();
this->pos_ = 0;
this->sep_count_ = 0;
buf_size = buffer_.get_available();
buf_size = buffer_.get_size();
this->frame_start_found_ = false;
continue;
}
Expand All @@ -218,7 +259,7 @@ void TransportLevelHandler::process_data()
this->current_frame_.reset();
this->pos_ = 0;
this->sep_count_ = 0;
buf_size = this->buffer_.get_available();
buf_size = this->buffer_.get_size();
this->frame_start_found_ = false;
continue;
}
Expand All @@ -245,7 +286,7 @@ void TransportLevelHandler::process_data()
void TransportLevelHandler::reset_protocol() noexcept
{
this->current_frame_.reset();
size_t bytesToDrop = this->buffer_.get_available();
size_t bytesToDrop = this->buffer_.get_size();
if (pos_ < bytesToDrop)
bytesToDrop = pos_;
this->drop_bytes_(bytesToDrop);
Expand Down Expand Up @@ -278,7 +319,7 @@ TransportLevelHandler::~TransportLevelHandler()

void TransportLevelHandler::clear_()
{
HAIER_LOGV("Clearing buffer, data size: %d", this->buffer_.get_available());
HAIER_LOGV("Clearing buffer, data size: %d", this->buffer_.get_size());
this->buffer_.clear();
this->pos_ = 0;
this->sep_count_ = 0;
Expand Down
Loading

0 comments on commit 60a0767

Please sign in to comment.