Vivian
2018-06-19
来源 :
阅读 1395
评论 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+频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号