Здравствуйте. Понадобился кольцевой буфер для многопоточного приложения. Большая часть того что удалось найти в интернете (в т.ч. <boost/circular_buffer.hpp>) ориентировано на объекты, которые по одному копируются в контейнер , а мне необходимо сохранять массивы структур (POD-типов) в стиле С и копирование каждой структуры будет слишком накладно. Попытался написать свой вариант, но как-то не очень (представлен ниже). Может ли кто-нибудь посоветовать готовое решение (готовый класс с подобным алгоритмом), или написать как сделать это оптимальнее. Заранее спасибо
#include <string.h>
#include <stdio.h>
#define RING_BUFFER_SIZE 25
class RingBuffer
{
public:
RingBuffer()
{
memset(m_Buffer,0,sizeof(m_Buffer));
memset(m_BufferCopy,0,sizeof(m_BufferCopy));
m_begin=0;
m_end=0;
}
~RingBuffer()
{
}
int WriteData(const const void *pData, int nDataLen)
{
char* pchData=(char*)pData;
int nFreeSpace=RING_BUFFER_SIZE-m_end;
if(m_begin<=m_end)
{
if (nFreeSpace>nDataLen)
{
memcpy(&m_Buffer[m_end],pchData,nDataLen);
m_end+=nDataLen;
m_Buffer[m_end]='f'; //признак окончания данных (для отладки)
}
else
{
memcpy(&m_Buffer[m_end],pchData,nFreeSpace);
memcpy(&m_Buffer[0],pchData+nFreeSpace,nDataLen-nFreeSpace);
m_end=nDataLen-nFreeSpace;
m_Buffer[m_end]='f'; //признак окончания данных (для отладки)
m_begin=m_end+1;
}
}
else
{
if (nFreeSpace>nDataLen)
{
memcpy(&m_Buffer[m_end],pchData,nDataLen);
m_end+=nDataLen;
m_Buffer[m_end]='f'; //признак окончания данных (для отладки)
m_begin=m_end+1;
}
else
{
memcpy(&m_Buffer[m_end],pchData,nFreeSpace);
memcpy(&m_Buffer[0],pchData+(nFreeSpace),nDataLen-nFreeSpace);
m_end=nDataLen-nFreeSpace;
m_Buffer[m_end]='f'; //признак окончания данных (для отладки)
m_begin=m_end+1;
}
}
return 0;
}
char* GetBufer()
{
memset(m_BufferCopy,0,sizeof(m_BufferCopy));
if (m_end==m_begin)
return m_BufferCopy;
if (m_end>m_begin)
memcpy(m_BufferCopy,m_Buffer,m_end);
else
{
memcpy(m_BufferCopy,m_Buffer+m_begin,RING_BUFFER_SIZE-m_begin);
memcpy(m_BufferCopy+(RING_BUFFER_SIZE-m_begin),m_Buffer,m_end);
}
return m_BufferCopy;
};
int DataLenght()
{
if (m_end==m_begin)
return 0;
if (m_end>m_begin)
return m_end;
else
return RING_BUFFER_SIZE-1;
};
void Clear()
{
memset(m_Buffer,0,sizeof(m_Buffer));
memset(m_BufferCopy,0,sizeof(m_BufferCopy));
m_begin=0;
m_end=0;
};
protected:
char m_Buffer[RING_BUFFER_SIZE];
char m_BufferCopy[RING_BUFFER_SIZE];
int m_nCount;
int m_begin; //begin data index
int m_end; //end data index
};
int _tmain(int argc, _TCHAR* argv[])
{
char message[]="123456789";
RingBuffer rb;
//в одном месте программы
for (int i=0;i<6;i++)
rb.WriteData(message,sizeof(message)-1);
//..
//где то в программе
pthread_mutex_lock(&m_FileMutex);
write(m_nFileDesc,rb.GetBufer(),rb.DataLenght());
rb.Clear();
pthread_mutex_unlock(&m_FileMutex);
return 0;
}