重构ringbuffer
parent
29c15e4016
commit
c8da1b73b6
|
@ -21,85 +21,71 @@ public:
|
||||||
~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;
|
||||||
|
*m_tail = data[0];
|
||||||
|
for(i = 1;i < len;i++){
|
||||||
|
T* tmp = m_tail;
|
||||||
|
if(m_tail < m_data_end) {
|
||||||
|
tmp++;
|
||||||
}
|
}
|
||||||
uint16_t bytes_write;
|
if(m_tail == m_data_end) {
|
||||||
if(len > mRemain){
|
tmp = m_data;
|
||||||
bytes_write = mRemain;
|
|
||||||
}else{
|
|
||||||
bytes_write = len;
|
|
||||||
}
|
}
|
||||||
|
if(tmp == m_head) {
|
||||||
if(mCurrentTail == mCurrentHead){
|
break;
|
||||||
/// |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;
|
|
||||||
}
|
}
|
||||||
|
(*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
|
||||||
|
|
Loading…
Reference in New Issue