重构ringbuffer

master
zcy 2021-12-21 16:05:00 +08:00
parent 29c15e4016
commit c8da1b73b6
1 changed files with 74 additions and 155 deletions

View File

@ -19,87 +19,73 @@ public:
uint32_t Length(); uint32_t Length();
~RingBuffer(); ~RingBuffer();
protected: protected:
T *mData; T *m_data;
uint64_t mSize; T *m_data_end;
uint64_t mCurrentTail; uint64_t m_size;
uint64_t mCurrentHead; T *m_tail;
uint16_t mRemain; T *m_head;
}; };
/**
* author : caiyuzheng
* function:
*/
template<typename T> template<typename T>
RingBuffer<T>::RingBuffer(uint64_t size) : RingBuffer<T>::RingBuffer(uint64_t size) :
mData(nullptr), m_data(nullptr),
mSize(0), m_size(0),
mCurrentTail(0), m_head(0),
mCurrentHead(0) m_tail(0)
{ {
mSize = size; m_size = size;
mData = new T[size]; m_data = new T[size];
mRemain = mSize; m_data_end = &m_data[size - 1];
m_head = m_tail = m_data;
} }
template<typename T> template<typename T>
RingBuffer<T>::~RingBuffer(){ RingBuffer<T>::~RingBuffer(){
delete[] mData; delete[] m_data;
} }
template<typename T> template<typename T>
void RingBuffer<T>::SetEmpty(){ void RingBuffer<T>::SetEmpty(){
this->mCurrentHead = this->mCurrentTail; this->m_head = this->m_tail;
this->mRemain = this->mSize;
} }
template<typename T> template<typename T>
int RingBuffer<T>::Copy(T *data,uint64_t len){ int RingBuffer<T>::Copy(T *data,uint64_t len){
if(data == nullptr) if(data == nullptr)
return -1; return -1;
if(mRemain == mSize)
return 0;
int bytes_read = 0;
if(len > (mSize - mRemain)){
bytes_read = mSize - mRemain;
}else{
bytes_read = len;
}
/// |start|head|.....|tail|end|
if(mCurrentTail >= mCurrentHead){
memcpy(data,&mData[mCurrentHead],sizeof(T)*bytes_read);
return bytes_read;
}
/// |start|...|tail|.....|head|...|end|
if(mCurrentHead > mCurrentTail){
int off = mCurrentHead + bytes_read;
if(off > mSize){
int tmp = mSize - mCurrentHead;
memcpy(data,&mData[mCurrentHead],(mSize - mCurrentHead)*sizeof(T));
memcpy(&data[mSize - mCurrentHead],&mData[0],(bytes_read - tmp)*sizeof(T));
return bytes_read;
}
if(off <= mSize){
memcpy(data,&mData[mCurrentHead],sizeof(T)*bytes_read);
return bytes_read;
}
}
} }
template<typename T> template<typename T>
uint32_t RingBuffer<T>::Size(){ uint32_t RingBuffer<T>::Size(){
return mSize; return m_size;
} }
template<typename T> template<typename T>
uint32_t RingBuffer<T>::Length(){ uint32_t RingBuffer<T>::Length(){
return mSize - mRemain; if(m_tail > m_head){
return uint32_t(m_tail - m_head + 1);
}
if(m_tail == m_head){
return 0;
}
if(m_head > m_tail){
return uint32_t(m_data_end - m_head + 1) + uint32_t(m_tail - m_data); // todo unsure
}
} }
template<typename T> template<typename T>
T RingBuffer<T>::At(uint64_t pos){ T RingBuffer<T>::At(uint64_t pos){
return mData[pos]; if(pos > (this->Length() - 1)){
return T{};
}
T* p = m_head + pos;
if(p > m_data_end){
p = p - m_size;
}
return *p;
} }
template<typename T> template<typename T>
@ -107,127 +93,60 @@ int RingBuffer<T>::Add(T *data,uint64_t len){
if(data == nullptr){ if(data == nullptr){
return -1; return -1;
} }
// buffer already full int i = 0;
if(mRemain == 0){ std::cout<<"123 "<<m_tail<<" " << m_head <<std::endl;
return -2; if(m_tail == m_head){
} std::cout<<"123"<<std::endl;
uint16_t bytes_write; *m_tail = data[0];
if(len > mRemain){ for(i = 1;i < len;i++){
bytes_write = mRemain; T* tmp = m_tail;
}else{ if(m_tail < m_data_end) {
bytes_write = len; tmp++;
}
if(mCurrentTail == mCurrentHead){
/// |start also head also tail|...|end|
if(mCurrentHead == 0){
memcpy(mData,data,bytes_write*sizeof(T));
mCurrentTail = bytes_write;
mRemain -= bytes_write;
return bytes_write;
}else{
/// |start |...| head also tail|...|end|
if(mCurrentTail + bytes_write < mSize){
memcpy(&mData[mCurrentTail],data,(bytes_write)*sizeof(T));
mCurrentTail += bytes_write;
mRemain -= bytes_write;
}else{
memcpy(&mData[mCurrentTail],data,(mSize - mCurrentTail)*sizeof(T));
std::cout<<"\r\n"<<(mCurrentTail + bytes_write)%mSize<<"\r\n";
memcpy(&mData[0],&data[mSize - mCurrentTail],(mCurrentTail + bytes_write)%mSize*sizeof(T));
mCurrentTail = (mCurrentTail + bytes_write)%mSize;
mRemain -= bytes_write;
return bytes_write;
} }
if(m_tail == m_data_end) {
tmp = m_data;
}
if(tmp == m_head) {
break;
}
(*tmp) = data[i];
m_tail = tmp;
}
}else{
std::cout<<"123"<<std::endl;
for(i = 0;i < len;i++){
T* tmp = m_tail;
if(m_tail < m_data_end) {
tmp++;
}
if(m_tail == m_data_end) {
tmp = m_data;
}
if(tmp == m_head) {
break;
}
(*tmp) = data[i];
m_tail = tmp;
} }
} }
/// |start|head|.....|tail|end| return i;
if(mCurrentTail > mCurrentHead){
uint16_t off = mCurrentTail + bytes_write;
if(off > mSize){
memcpy(&mData[mCurrentTail],data,
sizeof(T)*(mSize - mCurrentTail));
memcpy(mData,data + sizeof(T)*(mSize - mCurrentTail),
(bytes_write - (mSize - mCurrentTail))*sizeof(T));
mRemain -= bytes_write;
mCurrentTail = off - mSize;
return bytes_write;
}
if(off <= mSize){
memcpy(&mData[mCurrentTail],data,
sizeof(T)*bytes_write);
mRemain -= bytes_write;
if(off < mSize)
mCurrentTail += bytes_write;
else
mCurrentTail = 0;
return bytes_write;
}
}
/// |start|...|tail|.....|head|...|end|
if(mCurrentHead > mCurrentTail){
memcpy(&mData[mCurrentTail],data,sizeof(T)*(bytes_write));
mCurrentTail += bytes_write;
mRemain -= bytes_write;
return bytes_write;
}
} }
template<typename T> template<typename T>
int RingBuffer<T>::Take(T *data,uint64_t len){ int RingBuffer<T>::Take(T *data,uint64_t len){
if(data == nullptr) if(data == nullptr)
return -1; return -1;
if(mRemain == mSize)
return 0;
int bytes_read = 0;
if(len > (mSize - mRemain)){
bytes_read = mSize - mRemain;
}else{
bytes_read = len;
}
/// |start|head|.....|tail|end|
if(mCurrentTail >= mCurrentHead){
memcpy(data,&mData[mCurrentHead],sizeof(T)*bytes_read);
mCurrentHead += bytes_read;
mRemain = mSize - (mCurrentTail - mCurrentHead);
return bytes_read;
}
/// |start|...|tail|.....|head|...|end|
if(mCurrentHead > mCurrentTail){
int off = mCurrentHead + bytes_read;
if(off > mSize){
int tmp = mSize - mCurrentHead;
memcpy(data,&mData[mCurrentHead],(mSize - mCurrentHead)*sizeof(T));
memcpy(&data[mSize - mCurrentHead],&mData[0],(bytes_read - tmp)*sizeof(T));
mCurrentHead = off - mSize;
mRemain = mSize - (mCurrentTail - mCurrentHead);
return bytes_read;
}
if(off <= mSize){
memcpy(data,&mData[mCurrentHead],sizeof(T)*bytes_read);
if(off == mSize){
mCurrentHead = 0;
mRemain = mSize - mCurrentTail;
return bytes_read;
}
else{
mCurrentHead += bytes_read;
mRemain = mSize - ((mSize - mCurrentHead) + mCurrentTail);
return bytes_read;
}
}
}
} }
template<typename T> template<typename T>
uint32_t RingBuffer<T>::CanReadCount(){ uint32_t RingBuffer<T>::CanReadCount(){
return mSize - mRemain;
} }
template<typename T> template<typename T>
uint32_t RingBuffer<T>::CanWriteCount(){ uint32_t RingBuffer<T>::CanWriteCount(){
return mRemain;
} }
#endif #endif