最近,在优化服务器端底层代码时,遇到了一个比较影响系统性能的东西——缓存区,最已有的方案里,其采用了单缓冲区,每次需要空间时,都会检查缓冲区空闲空间是否满足,如果满足还得进行移动内存的操作(想必搞过服务器开发的同事,这点深有体会吧),当数据交换量猛增时,这个方案效果立马显现,于是自己私下写了一个简单版的循环缓存,原理很简单,在这之上自己将代码进行了规整和优化,并替换了原来的单缓存区方案,效果显著,好了,在这里,只放测试用的原始代码,至于优化代码鉴于商业原因,还是不放了,代码如下:
#ifndef __CIRBUFFER__H #define __CIRBUFFER__H #include <iostream> #include <stdlib.h> #include <string.h> #include <boost/assert.hpp> using namespace std; using namespace boost; #define DEFAULT_SIZE 20 class CirBuffer { public: CirBuffer(int maxSize):bufferSize(maxSize) { readPtr = writePtr = 0; isReadFast = isWriteFast = false; buffer = new char[bufferSize]; assert(buffer); bzero(buffer,bufferSize); } ~CirBuffer() { assert(buffer); delete[] buffer; } int getBufferSize() { return bufferSize; } void display() { cout<<"writePtr:"<<writePtr<<" readPtr:"<<readPtr<<" buffer:"<<buffer<<endl; } int usedMemorySize() { int len = 0; if(writePtr > readPtr) len = writePtr - readPtr; else if(readPtr > writePtr) len = bufferSize - readPtr + writePtr; return len; } void addMemory(int size,int len) { assert(buffer); int freelen = bufferSize - len; while(freelen < size) { bufferSize = bufferSize<<1; freelen = bufferSize - len; } char* newBuffer = new char[bufferSize]; assert(newBuffer); bzero(newBuffer,bufferSize); if(writePtr > readPtr) { memcpy(newBuffer,&buffer[readPtr],writePtr-readPtr); delete[] buffer; buffer = newBuffer; readPtr = 0; writePtr = writePtr-readPtr; } else { int end = bufferSize - readPtr; memcpy(newBuffer,&buffer[readPtr],end); memcpy(&newBuffer[end],buffer,writePtr); delete[] buffer; buffer = newBuffer; readPtr = 0; writePtr = end + writePtr; } } void reserveBuffer(int size) { int usedLen = usedMemorySize(); if(bufferSize < usedLen + size) addMemory(size,usedLen); } void readMv(int len) { if(len > bufferSize) return; readPtr = (readPtr + len) %(bufferSize); if(readPtr == writePtr) isReadFast = true; else isReadFast = false; display(); } void writeMv(int len) { if(len > bufferSize) return; writePtr = (writePtr + len) %(bufferSize); if(writePtr == readPtr) isWriteFast = true; else isWriteFast = false; display(); } void write(const char* Buffer,int size) { assert(Buffer); reserveBuffer(size); if(writePtr > readPtr) { int end = bufferSize - writePtr; if(end >= size) { memcpy(&buffer[writePtr],Buffer,size); writeMv(size); } else { memcpy(&buffer[writePtr],Buffer,end); memcpy(buffer,&Buffer[end],size-end); writeMv(size); } } else if(writePtr < readPtr) { int len = readPtr - writePtr; if(len >= size) { memcpy(&buffer[writePtr],Buffer,size); writeMv(size); } } else { if(isReadFast) { int end = bufferSize - writePtr; if(end >= size) { memcpy(&buffer[writePtr],Buffer,size); writeMv(size); } else { memcpy(&buffer[writePtr],Buffer,end); memcpy(buffer,&Buffer[end],size-end); writeMv(size); } } else if(!isWriteFast && !isReadFast) { memcpy(&buffer[writePtr],Buffer,size); writeMv(size); } } } void read(char* Buffer,int size) { assert(Buffer); if(writePtr > readPtr) { int len = writePtr - readPtr; int readlen = (len > size)?size:len; memcpy(Buffer,&buffer[readPtr],readlen); readMv(readlen); } else if(writePtr < readPtr) { int end = bufferSize - readPtr; if(end >= size) { memcpy(Buffer,&buffer[readPtr],size); readMv(size); } else { int len = (size > end + readPtr)?(readPtr):(size-end); memcpy(Buffer,&buffer[readPtr],end); memcpy(&Buffer[end],buffer,len); readMv(len+end); } } else { if(isWriteFast) { int end = bufferSize - readPtr; if(end >= size) { memcpy(Buffer,&buffer[readPtr],size); readMv(size); } else { memcpy(Buffer,&buffer[readPtr],end); memcpy(&Buffer[end],buffer,size-end); readMv(size); } } } } private: char* buffer; int readPtr; int writePtr; int bufferSize; bool isReadFast; bool isWriteFast; }; #endif
测试程序:
#include "CirBuffer.h" int main() { CirBuffer cirBuffer(DEFAULT_SIZE); const char* str = "Hello,everyone"; char buffer[14]; for(int i=0;i<4;i++) { cirBuffer.write(str,strlen(str)); bzero(buffer,sizeof(buffer)); cirBuffer.read(buffer,sizeof(buffer)); } cout<<cirBuffer.getBufferSize()<<endl; return 0; }
测试结果:
writePtr:14 readPtr:0 buffer:Hello,everyone
writePtr:14 readPtr:14 buffer:Hello,everyone
writePtr:8 readPtr:14 buffer:everyoneeryoneHello,
writePtr:8 readPtr:8 buffer:everyoneeryoneHello,
writePtr:2 readPtr:8 buffer:neeryoneHello,everyo
writePtr:2 readPtr:2 buffer:neeryoneHello,everyo
writePtr:16 readPtr:2 buffer:neHello,everyoneeryo
writePtr:16 readPtr:16 buffer:neHello,everyoneeryo
20
总结
本篇博文主要是实现了一个循环缓冲区,设计思路比较简单,实用性不是很好,但是其中的一些思想可以借鉴,循环缓存区在实际应用中,使用的还是很多的,目前针对缓冲区设计一般集中在循环缓存、双循环缓存以及循环缓存链等,如果有时间的话,会实现一个双循环缓存和循环缓存链,主要的目的就是要加深对缓存系统的认识和理解,好了,本篇博文到此结束,多谢了
如果需要,请注明转载,多谢