如何用C++语言实现循环缓存区
Vivian 2018-06-19 来源 : 阅读 885 评论 0

摘要:本文主要向大家介绍了如何用C++语言实现循环缓存区,通过具体的代码向大家展示,希望对大家学习C++语言有所帮助。

    本文主要向大家介绍了如何用C++语言实现循环缓存区,通过具体的代码向大家展示,希望对大家学习C++语言有所帮助。

    最近,在优化服务器端底层代码时,遇到了一个比较影响系统性能的东西——缓存区,最已有的方案里,其采用了单缓冲区,每次需要空间时,都会检查缓冲区空闲空间是否满足,如果满足还得进行移动内存的操作(想必搞过服务器开发的同事,这点深有体会吧),当数据交换量猛增时,这个方案效果立马显现,于是自己私下写了一个简单版的循环缓存,原理很简单,在这之上自己将代码进行了规整和优化,并替换了原来的单缓存区方案,效果显著,好了,在这里,只放测试用的原始代码,至于优化代码鉴于商业原因,还是不放了,代码如下:

[cpp] view plain copy print?
1. #ifndef __CIRBUFFER__H  
2. #define __CIRBUFFER__H  
3.   
4. #include <iostream>  
5. #include <stdlib.h>  
6. #include <string.h>  
7. #include <boost/assert.hpp>  
8. using namespace std;  
9. using namespace boost;  
10.   
11. #define DEFAULT_SIZE 20  
12. class CirBuffer  
13. {  
14.     public:  
15.         CirBuffer(int maxSize):bufferSize(maxSize)  
16.         {  
17.             readPtr = writePtr = 0;  
18.             isReadFast = isWriteFast = false;  
19.             buffer = new char[bufferSize];  
20.             assert(buffer);  
21.             bzero(buffer,bufferSize);  
22.         }  
23.         ~CirBuffer()  
24.         {  
25.             assert(buffer);  
26.             delete[] buffer;  
27.         }  
28.   
29.         int getBufferSize()  
30.         {  
31.             return bufferSize;  
32.         }  
33.   
34.         void display()  
35.         {  
36.             cout<<"writePtr:"<<writePtr<<"  readPtr:"<<readPtr<<" buffer:"<<buffer<<endl;  
37.         }  
38.   
39.         int usedMemorySize()  
40.         {  
41.             int len = 0;  
42.             if(writePtr > readPtr)  
43.                 len = writePtr - readPtr;  
44.             else if(readPtr > writePtr)  
45.                 len = bufferSize - readPtr + writePtr;  
46.             return len;  
47.         }  
48.         void addMemory(int size,int len)  
49.         {  
50.             assert(buffer);  
51.             int freelen = bufferSize - len;  
52.             while(freelen < size)  
53.             {  
54.                 bufferSize = bufferSize<<1;  
55.                 freelen = bufferSize - len;  
56.             }  
57.   
58.             char* newBuffer = new char[bufferSize];  
59.             assert(newBuffer);  
60.             bzero(newBuffer,bufferSize);  
61.             if(writePtr > readPtr)  
62.             {  
63.                 memcpy(newBuffer,&buffer[readPtr],writePtr-readPtr);  
64.                 delete[] buffer;  
65.                 buffer = newBuffer;  
66.                 readPtr = 0;  
67.                 writePtr = writePtr-readPtr;  
68.             }  
69.             else  
70.             {  
71.                 int end = bufferSize - readPtr;  
72.                 memcpy(newBuffer,&buffer[readPtr],end);  
73.                 memcpy(&newBuffer[end],buffer,writePtr);  
74.                 delete[] buffer;  
75.                 buffer = newBuffer;  
76.                 readPtr = 0;  
77.                 writePtr = end + writePtr;  
78.             }  
79.         }  
80.   
81.         void reserveBuffer(int size)  
82.         {  
83.             int usedLen = usedMemorySize();  
84.             if(bufferSize < usedLen + size)  
85.                 addMemory(size,usedLen);  
86.         }  
87.         void readMv(int len)  
88.         {  
89.             if(len > bufferSize) return;  
90.             readPtr = (readPtr + len) %(bufferSize);  
91.             if(readPtr == writePtr)  
92.                 isReadFast = true;  
93.             else  
94.                 isReadFast = false;  
95.             display();  
96.         }  
97.         void writeMv(int len)  
98.         {  
99.             if(len > bufferSize) return;  
100.             writePtr = (writePtr + len) %(bufferSize);  
101.             if(writePtr == readPtr)  
102.                 isWriteFast = true;  
103.             else  
104.                 isWriteFast = false;  
105.             display();  
106.         }  
107.   
108.         void write(const char* Buffer,int size)  
109.         {  
110.             assert(Buffer);  
111.             reserveBuffer(size);  
112.             if(writePtr > readPtr)  
113.             {  
114.                 int end = bufferSize - writePtr;  
115.                 if(end >= size)  
116.                 {  
117.                     memcpy(&buffer[writePtr],Buffer,size);  
118.                     writeMv(size);  
119.                 }  
120.                 else  
121.                 {  
122.                     memcpy(&buffer[writePtr],Buffer,end);  
123.                     memcpy(buffer,&Buffer[end],size-end);  
124.                     writeMv(size);  
125.                 }  
126.             }  
127.             else if(writePtr < readPtr)  
128.             {  
129.                 int len = readPtr - writePtr;  
130.                 if(len >= size)  
131.                 {  
132.                     memcpy(&buffer[writePtr],Buffer,size);  
133.                     writeMv(size);  
134.                 }  
135.             }  
136.             else  
137.             {  
138.                 if(isReadFast)  
139.                 {  
140.                     int end = bufferSize - writePtr;  
141.                     if(end >= size)  
142.                     {  
143.                         memcpy(&buffer[writePtr],Buffer,size);  
144.                         writeMv(size);  
145.                     }  
146.                     else  
147.                     {  
148.                         memcpy(&buffer[writePtr],Buffer,end);  
149.                         memcpy(buffer,&Buffer[end],size-end);  
150.                         writeMv(size);  
151.                     }  
152.                 }  
153.                 else if(!isWriteFast && !isReadFast)  
154.                 {  
155.                     memcpy(&buffer[writePtr],Buffer,size);  
156.                     writeMv(size);  
157.                 }  
158.             }  
159.         }  
160.   
161.         void read(char* Buffer,int size)  
162.         {  
163.             assert(Buffer);  
164.             if(writePtr > readPtr)  
165.             {  
166.                 int len = writePtr - readPtr;  
167.                 int readlen = (len > size)?size:len;  
168.                 memcpy(Buffer,&buffer[readPtr],readlen);  
169.                 readMv(readlen);  
170.             }  
171.             else if(writePtr < readPtr)  
172.             {  
173.                 int end = bufferSize - readPtr;  
174.                 if(end >= size)  
175.                 {  
176.                     memcpy(Buffer,&buffer[readPtr],size);  
177.                     readMv(size);  
178.                 }  
179.                 else  
180.                 {  
181.                     int len = (size > end + readPtr)?(readPtr):(size-end);  
182.                     memcpy(Buffer,&buffer[readPtr],end);  
183.                     memcpy(&Buffer[end],buffer,len);  
184.                     readMv(len+end);  
185.                 }  
186.             }  
187.             else  
188.             {  
189.                 if(isWriteFast)  
190.                 {  
191.                     int end = bufferSize - readPtr;  
192.                     if(end >= size)  
193.                     {  
194.                         memcpy(Buffer,&buffer[readPtr],size);  
195.                         readMv(size);  
196.                     }  
197.                     else  
198.                     {  
199.                         memcpy(Buffer,&buffer[readPtr],end);  
200.                         memcpy(&Buffer[end],buffer,size-end);  
201.                         readMv(size);  
202.                     }  
203.                 }  
204.             }  
205.         }  
206.     private:  
207.         char* buffer;  
208.         int readPtr;  
209.         int writePtr;  
210.         int bufferSize;  
211.         bool isReadFast;  
212.         bool isWriteFast;  
213. };

214. #endif  

Main.cpp

[cpp] view plain copy print?
1. #include "CirBuffer.h"  
2.   
3. int main()  
4. {  
5.     CirBuffer cirBuffer(DEFAULT_SIZE);  
6.     const char* str = "Hello,everyone";  
7.     char buffer[14];  
8.     for(int i=0;i<4;i++)  
9.     {  
10.         cirBuffer.write(str,strlen(str));  
11.         bzero(buffer,sizeof(buffer));  
12.         cirBuffer.read(buffer,sizeof(buffer));  
13.     }  
14.     cout<<cirBuffer.getBufferSize()<<endl;  
15.     return 0;  
16. }

 

测试结果:

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+频道!

本文由 @Vivian 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程