循环缓存区之C++实现
来源:互联网 发布:问卷调查的app软件 编辑:程序博客网 时间:2024/06/02 02:46
最近,在优化服务器端底层代码时,遇到了一个比较影响系统性能的东西——缓存区,最已有的方案里,其采用了单缓冲区,每次需要空间时,都会检查缓冲区空闲空间是否满足,如果满足还得进行移动内存的操作(想必搞过服务器开发的同事,这点深有体会吧),当数据交换量猛增时,这个方案效果立马显现,于是自己私下写了一个简单版的循环缓存,原理很简单,在这之上自己将代码进行了规整和优化,并替换了原来的单缓存区方案,效果显著,好了,在这里,只放测试用的原始代码,至于优化代码鉴于商业原因,还是不放了,代码如下:
#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 20class 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;};#endifMain.cpp
#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
总结
本篇博文主要是实现了一个循环缓冲区,设计思路比较简单,实用性不是很好,但是其中的一些思想可以借鉴,循环缓存区在实际应用中,使用的还是很多的,目前针对缓冲区设计一般集中在循环缓存、双循环缓存以及循环缓存链等,如果有时间的话,会实现一个双循环缓存和循环缓存链
- 循环缓存区之C++实现
- 循环缓存区之C++实现
- 数据结构C语言实现之循环队列
- 数据结构C语言实现之循环队列
- 数据结构之---C语言实现循环队列
- C实现循环双链表
- 循环队列实现(C++)
- C 循环队列实现
- 循环队列 c 实现!!!!
- 【C++】实现循环队列
- C语言之清空缓存区
- 数据结构C语言实现之循环队列----数组形式---简单化
- 数据结构之---c语言实现循环单链表操作
- 数据结构基础之循环队列C语言实现
- 数据结构之循环单链表(C语言实现)
- c语言的循环之for循环
- C语言实现LRU缓存
- C实现循环右移
- LabVIEW 读取 DLL 函数
- 线程的生命周期
- 单例模式(Singleton)
- Java面向对象
- 判断题(PAT-1061)
- 循环缓存区之C++实现
- Lua 中 pairs 与 ipairs 区别
- manve的生命周期
- javascript实现轮播图效果
- linux 学习 (二)
- Mac OS X 下修改 Google Chrome 显示语言的方法
- 冒泡排序
- Android笔试题——三七互娱的一些笔试题
- 分布式系统组成:分布式缓存、存储、消息队列